首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

Comet ajax长连接及demo,该如何处理

2012-12-28 
Comet ajax长连接及demo最近一个项目里要用到b/s即时通讯.又不想用第三方的(主要是怕有版权问题).于是自己

Comet ajax长连接及demo
最近一个项目里要用到b/s即时通讯.又不想用第三方的(主要是怕有版权问题).于是自己研究一下,按传统的ajax定时轮询服务器来获取消息的办法的缺点就是不够实时,而且不停的查询造成服务器压力不小.

理论:

在网上找到一篇文章Comet:基于 HTTP 长连接的“服务器推”技术(http://www.ibm.com/developerworks/cn/web/wa-lo-comet/)
发现很不错.所以自己试着写了一个demo.主要实现下面的技术
一.服务器端会阻塞请求直到有数据传递或超时才返回。 


bool flag = true;
//服务器阻塞.直到有消息返回       
while (flag)
      {
...
          //信息已接收,返回应答
          HttpContext.Current.Response.Write("state.savesuccess");
          flag = false;
      }

二.客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。 

function ConnectHandler() {
...
   var result = data;
   if (result != "") {
       //当收到服务器信息后再次发起连接
       ConnectHandler();
   }
}

三.当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。

//如果有给对方的消息则推送.然后标记已读
StringBuilder builderMsg = new StringBuilder();
StringBuilder builderIds = new StringBuilder();
if (listMsg != null && listMsg.Count > 0)
   {
...
 
大致上就是根据上面的理论来操作的.就像是一个搬运工,搬完了东西就跑去包工头那里.包头工手上有东西了马上给搬运工.这个搬运工等的时候就是长连接.传统的ajax是不断询问,相当于搬运工手里没东西也要不停来回跑.

示例DEMO
先看个效果吧



1.新建立一个登录页

你的姓名: <asp:TextBox ID="txtSenderName" runat="server"></asp:TextBox> <br />
    接收方姓名:<asp:TextBox ID="txtReciverName" runat="server"></asp:TextBox> <br />
    <input type="button" value="登录" />

<script type="text/javascript">
    $("input[value='登录']").click(function() {
        location = "IM.aspx?Sender=" +encodeURI( $('#<%=txtSenderName.ClientID %>').val() ) + "&Reciver=" +encodeURI( $('#<%=txtReciverName.ClientID %>').val() );
    });
</script>

2.新建立一个聊天界面IM.aspx
这里主要左边是一个在线会员列表,右边是聊天区
当登录页面后,系统马上会连接到处理页,看看是否有用户的消息.如果有则显示出来
[code=JScript]
//登录即请求
    $(function() {
        ConnectHandler();
    });


用户发送一条消息传给处理页Handler.ashx,处理页会阻塞此连接(相当于保持连接).然后保存此消息到数据库,成功返回应答告诉用户消息已经保存,可以再输入下一条消息.这就像QQ信息没发出时[发送]按钮是灰色一样的道理.
当有用户消息时,系统会输出消息

else
            {
                //获取所有当前请求者的消息并返回
                IList<IMMessage> listMsg = IMMessage.GetMessageListBySender(msg.Sender);
                string strMsg = string.Empty;
                //如果有给对方的消息则推送.然后标记已读
                StringBuilder builderMsg = new StringBuilder();


                StringBuilder builderIds = new StringBuilder();
                if (listMsg != null && listMsg.Count > 0)
                {
                    for (int i = 0; i < listMsg.Count; i++)
                    {
                        if (i == listMsg.Count - 1)
                            builderMsg.Append(listMsg[i].AutoID + "|" + listMsg[i].Sender + "|" + listMsg[i].Msg.Replace("|", "").Replace(",", ".") + "|" + listMsg[i].SendTime.ToString());
                        else
                            builderMsg.Append(listMsg[i].AutoID + "|" + listMsg[i].Sender + "|" + listMsg[i].Msg.Replace("|", "").Replace(",", ".") + "|" + listMsg[i].SendTime.ToString() + ",");
                    }
                    HttpContext.Current.Response.Write(builderMsg.ToString());
                    flag = false;
                }
            }


上面传送过来的消息在用户获取后再标记为已读

else if (result.indexOf("|") != -1) {
                    var id = result.split('|')[0];
                    var element = $("#showmsgwindow").find("div[id='msg_" + id + "']");
                    if (element.length == 0) { //判断是否已经输出到页面
                        $("#showmsgwindow").append("<div id='msg_" + id + "' style='margin:3px 0'><b>" + result.split('|')[1] + "</b> (" + result.split('|')[3] + ") 说:<br/>" + result.split('|')[2] + "</div>");
                        delmsg(id);//标记为已读,不会再输出到页面
                    }


                }



至于维护在线会员.我在GLOBAL.ASAX全局页面中定义了一个时间控件

//定时器,检测会员在线情况
    private System.Threading.Timer timeAuto;
    protected void Application_Start(object sender, EventArgs e)
    {
        //定时器 间隔10秒 随应用程序启动            
        timeAuto = new System.Threading.Timer(new System.Threading.TimerCallback(CheckUserOnlie), this, 0, 20 * 1000);
    }
    private void CheckUserOnlie(object obj)
    {
        OnlineUser.CheckOnlineUser();
    }


差不多就这些吧.欢迎拍砖!!!
[解决办法]
哦,长链接一样耗资源
[解决办法]
可以把这个程序发我吗? 我想参考下  763386681@qq.com 谢谢

热点排行