今天和一个同事聊到了关于Web(传统)实时通讯的问题,其中包括轮询、长轮询、长连接。最后同事说长轮询对与.net来说比较难以实现(不使用任何框架)。
首先看一下什么是“长轮询”!定义如下:
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求。
缺点:服务器hold连接会消耗资源。
以上 “长轮询” 定义是我在网上抄的哦!
那么是不是只要满足以上所诉的内容长轮询是不是就成立呢?那就尝试一下!
建立数据库:
- ifnotexists(select1fromsys.databaseswherename='beidoudemo')
- begin
- CreateDatabasebeidoudemo
- end
- go
- usebeidoudemo
- go
- ifexists(select1fromsysobjectswherename='AjaxPolling'andtype='u')
- begin
- droptableAjaxPolling
- end
- go
- CreatetableAjaxPolling
- (
- idintidentityPrimarykey,
- userNamevarchar(30)notnull,
- passwordKeyvarchar(50)notnull
- )
选用Jquery中的AJAX方法发送异步请求,前台省了很多事情了!
具体代码请看:
- <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="LongPolling.aspx.cs"Inherits="AjaxFinder.LongPolling"%>
- <!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <htmlxmlns="http://www.w3.org/1999/xhtml">
- <headrunat="server">
- <scriptsrc="Scripts/jquery-1.4.1.js"type="text/javascript"></script>
- <title></title>
- <scripttype="text/javascript">
- varuserID=0;
- functionSendXHR(){
- $.ajax({
- type:"post",//AJAX请求类型
- url:"LongPollingServer.ashx",//请求url
- cache:false,//无缓存
- timeout:1000*80,//AJAX请求超时时间为60秒
- data:{time:60,userID:userID},//参数time时间为最多等待(后台保持)时间(60秒无论是否有数据立即返回),单位为秒。userID判断诗句是否为新数据的标识
- success:function(data,textStatus){
- varobj=document.getElementById("NameDisplay");
- //判断返回成功还是失败如果后台保持连接的时间一到并且没有新数据就会返回fail开头失败的数据
- if(data!=null&&data!=""&&!(data.indexOf("fail")!=-1)){
- varstrarr=data.split(",");
- //alert(strarr[0]);
- userID=strarr[0];
- obj.innerHTML="亲!有新用户注册哦!用户名:"+strarr[1];
- }
- else{
- obj.innerHTML="亲!暂无新用户注册哦";
- }
- SendXHR();//请求后立即发起AJAX请求
- },
- error:function(XMLHttpRequest,textStatus,errorThrown){
- //NewErrordosomething
- if(textStatus=="timeout"){
- //超时间
- SendXHR();
- }
- }
- });
- }
- window.
- SendXHR();
- }
- </script>
- </head>
- <body>
- <formid="form1"runat="server">
- <div>
- </div>
- <divid="NameDisplay">
- </div>
- </form>
- </body>
- </html>
前台数据请求已经准备好了,接下来看一下后台代码实现。具体代码如下:
- usingSystem;
- usingSystem.Collections.Generic;
- usingSystem.Linq;
- usingSystem.Web;
- usingSystem.Text;
- usingSystem.Net;
- usingSystem.Threading;
- usingSystem.Data;
- namespaceAjaxFinder
- {
- ///<summary>
- ///AJAX长轮询后台处理页面
- ///主要用于保持连接
- ///有数据返回,无数据继续保持连接超时返回
- ///author:bluescreen
- ///Date:2013-03-14
- ///blog:http://www.cnblogs.com/bluescreen/
- ///请不要关注代码编写规范等一些问题。这仅仅是一个DEMO
- ///还存在诸多问题
- ///</summary>
- publicclassLongPollingServer:IHttpHandler
- {
- publicvoidProcessRequest(HttpContextcontext)
- {
- /*
- context.Response.ContentType="text/plain";
- context.Response.Write("HelloWorld");*/
- intSendTime=0;//最多等待时间
- intuserID=0;//上一次的用户ID
- if(context.Request.Form["time"]!=null&&context.Request.Form["time"].ToString()!="")
- {
- SendTime=int.Parse(context.Request.Form["time"].ToString());//接收传来的的后台要保持时间
- }
- if(context.Request.Form["userID"]!=null&&context.Request.Form["userID"].ToString()!="")
- {
- userID=int.Parse(context.Request.Form["userID"].ToString());
- }
- inti=0;//计算超时时间(秒)
- while(true)
- {
- Thread.Sleep(1000);//停留一千毫秒(1秒)
- i++;
- if(i<SendTime)
- {
- if(NameStr(userID)!="")
- {
- context.Response.Write(NameStr(userID));
- break;
- }
- }
- if(i==SendTime)
- {
- context.Response.Write("fail:无数据");
- break;
- }
- }
- }
- ///<summary>
- ///获得用户名
- ///</summary>
- ///<paramname="userID"></param>
- ///<returns></returns>
- privatestringNameStr(intuserID)
- {
- stringresult=string.Empty;
- stringsqlstr="selecttop1ID,UserNamefromAjaxPollingOrderbyIDdesc";
- DataSetds=newDataSet();
- ds=sqlHelper.Query(sqlstr,null);
- if(ds!=null)
- {
- if(ds.Tables[0].Rows.Count>=1)
- {
- if(int.Parse(ds.Tables[0].Rows[0][0].ToString())!=userID||0==int.Parse(ds.Tables[0].Rows[0][0].ToString()))
- {
- result=ds.Tables[0].Rows[0][0].ToString()+","+ds.Tables[0].Rows[0][1].ToString();
- }
- }
- }
- returnresult;
- }
- publicboolIsReusable
- {
- get
- {
- returnfalse;
- }
- }
- }
- }
以上代码经过测试的确符合 “长轮询” 的说法,那是不是可以说是长轮询呢?各位大牛你们怎么看?
原文链接:https://www.f2er.com/ajax/166646.html