AJAX长轮询之DotNet实现

作者:   出处:互联网   2015-07-05 22:59:44   阅读:2

今天和一个同事聊到了关于Web(传统)实时通讯的问题,其中包括轮询、长轮询、长连接。最后同事说长轮询对与.net来说比较难以实现(不使用任何框架)。


 

首先看一下什么是 长轮询 !定义如下:


 

长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。


 

优点:在无消息的情况下不会频繁的请求。


 

缺点:服务器hold连接会消耗资源。


 

以上 长轮询 定义是在网上抄的哦!


 

那么是不是只要满足以上所诉的内容长轮询是不是就成立呢?那就尝试一下!


 

建立数据库:


 

if not exists(select 1 from sys.databases where name='beidoudemo')  begin  Create Database beidoudemo  end  go  use beidoudemo  go  if exists(select 1 from sysobjects where name='AjaxPolling' and type='u')  begin  drop table AjaxPolling  end  go  Create table AjaxPolling  (  id int identity Primary key,  userName varchar(30) not null,  passwordKey varchar(50) not null ) 


 

选用Jquery中的AJAX方法发送异步请求,前台省了很多事情了!


 

具体代码请看:


 

 %@ Page Language= C#  AutoEventWireup= true  CodeBehind= LongPolling.aspx.cs  Inherits= AjaxFinder.LongPolling  %   !DOCTYPE html PUBLIC  -//W3C//DTD XHTML 1.0 Transitional//EN   http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd   html xmlns= http://www.w3.org/1999/xhtml   head runat= server   script src= Scripts/jquery-1.4.1.js  type= text/javascript /script   title /title   script type= text/javascript  var userID = 0;  function SendXHR() {  $.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) {  var obj = document.getElementById( NameDisplay );  //判断返回成功还是失败 如果后台保持连接的时间一到并且没有新数据就会返回fail开头失败的数据  if (data != null   data !=     !(data.indexOf( fail ) != -1)) {  var strarr = data.split( , );  // alert(strarr[0]);  userID = strarr[0];  obj.innerHTML =  亲!有新用户注册哦!用户名:  + strarr[1];  }  else {  obj.innerHTML =  亲!暂无新用户注册哦 ;  }  SendXHR();//请求后立即发起AJAX请求  },  error: function (XMLHttpRequest, textStatus, errorThrown) {  //New Error do something  if (textStatus ==  timeout ) {  //超时间  SendXHR();  }  }  });  }  window.onload = function () {  SendXHR();  }   /script   /head   body   form id= form1  runat= server   div   /div   div id= NameDisplay   /div   /form   /body   /html  


 

前台数据请求已经准备好了,接下来看一下后台代码实现。具体代码如下:


 

using System;  using System.Collections.Generic;  using System.Linq;  using System.Web;  using System.Text;  using System.Net;  using System.Threading;  using System.Data;  namespace AjaxFinder  {  ///  summary  /// AJAX长轮询后台处理页面  /// 主要用于保持连接  /// 有数据返回,无数据继续保持连接超时返回  /// author:bluescreen  /// Date :2015-03-14  /// blog:http://www.cnblogs.com/bluescreen/  /// 请不要关注代码编写规范等一些问题。这仅仅是一个DEMO  /// 还存在诸多问题  ///  /summary  public class LongPollingServer : IHttpHandler  {  public void ProcessRequest(HttpContext context)  {  /*  context.Response.ContentType =  text/plain  context.Response.Write( Hello World */ int SendTime = 0; //最多等待时间  int userID = 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());  }  int i = 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  ///  param name= userID /param  ///  returns /returns  private string NameStr(int userID)  {  string result = string.Empty;  string Sqlstr =  select top 1 ID,UserName from AjaxPolling Order by ID desc ;  DataSet ds = new DataSet();  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();  }  }  }  return result;  }  public bool IsReusable  {  get {  return false;  }  }  }  } 


 

以上代码经过测试的确符合 长轮询 的说法,那是不是可以说是长轮询呢?各位大牛你们怎么看?

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat