日期:2014-05-17  浏览次数:20427 次

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;
                //如