AJAX长轮询之DotNet实现

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

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

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

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

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

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

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

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

建立数据库:

  1. if not exists(select 1 from  sys.databases where name='beidoudemo')  
  2. begin  
  3. Create Database beidoudemo  
  4. end  
  5. go  
  6.  
  7. use beidoudemo  
  8. go  
  9. if exists(select 1 from sysobjects where name='AjaxPolling' and type='u')  
  10. begin  
  11.   drop table AjaxPolling  
  12. end  
  13. go  
  14. Create table AjaxPolling  
  15. (  
  16.   id int identity Primary key,  
  17.   userName varchar(30) not null,  
  18.   passwordKey varchar(50) not null 

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

具体代码请看:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LongPolling.aspx.cs" Inherits="AjaxFinder.LongPolling" %>  
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head runat="server">  
  6.     <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>  
  7.     <title></title>  
  8.     <script type="text/javascript">  
  9.         var userID = 0;  
  10.         function SendXHR() {  
  11.             $.ajax({  
  12.                 type: "post"//AJAX请求类型  
  13.                 url: "LongPollingServer.ashx"//请求url  
  14.                 cache: false,  //无缓存  
  15.                 timeout: 1000 * 80,  //AJAX请求超时时间为60秒  
  16.                 data: { time: 60, userID: userID }, //参数time时间为最多等待(后台保持)时间(60秒无论是否有数据立即返回),单位为秒。userID判断诗句是否为新数据的标识  
  17.                 success: function (data, textStatus) {  
  18.                     var obj = document.getElementById("NameDisplay");  
  19.                     //判断返回成功还是失败  如果后台保持连接的时间一到并且没有新数据就会返回fail开头失败的数据  
  20.                     if (data != null && data != "" && !(data.indexOf("fail") != -1)) {  
  21.                         var strarr = data.split(",");  
  22.                        // alert(strarr[0]);  
  23.                         userID = strarr[0];  
  24.                         obj.innerHTML = "亲!有新用户注册哦!用户名:" + strarr[1];  
  25.                     }  
  26.                     else {  
  27.                         obj.innerHTML = "亲!暂无新用户注册哦";  
  28.                     }  
  29.                     SendXHR();//请求后立即发起AJAX请求  
  30.                 },  
  31.                 error: function (XMLHttpRequest, textStatus, errorThrown) {  
  32.                     //New Error do something  
  33.                     if (textStatus == "timeout") {  
  34.                         //超时间  
  35.                         SendXHR();  
  36.                     }  
  37.                 }  
  38.  
  39.             });  
  40.         }  
  41.         window.onload = function () {  
  42.             SendXHR();  
  43.         }  
  44.     </script>  
  45. </head>  
  46. <body>  
  47.     <form id="form1" runat="server">  
  48.     <div>  
  49.     </div>  
  50.         <div id="NameDisplay">  
  51.         </div>  
  52.     </form>  
  53. </body>  
  54. </html> 

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

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Text;  
  6. using System.Net;  
  7. using System.Threading;  
  8. using System.Data;  
  9.  
  10. namespace AjaxFinder  
  11. {  
  12.     /// <summary>  
  13.     /// AJAX长轮询后台处理页面  
  14.     /// 主要用于保持连接  
  15.     /// 有数据返回,无数据继续保持连接超时返回  
  16.     /// author:bluescreen  
  17.     /// Date  :2013-03-14  
  18.     /// blog:http://www.cnblogs.com/bluescreen/  
  19.     /// 请不要关注代码编写规范等一些问题。这仅仅是一个DEMO  
  20.     /// 还存在诸多问题  
  21.     /// </summary>  
  22.     public class LongPollingServer : IHttpHandler  
  23.     {  
  24.  
  25.         public void ProcessRequest(HttpContext context)  
  26.         {  
  27.            /*  
  28.             context.Response.ContentType = "text/plain";  
  29.             context.Response.Write("Hello World");*/ 
  30.             int SendTime = 0;  //最多等待时间  
  31.             int userID = 0;    //上一次的用户ID  
  32.             if (context.Request.Form["time"] != null&&context.Request.Form["time"].ToString()!="")  
  33.             {  
  34.                 SendTime =int.Parse(context.Request.Form["time"].ToString());//接收传来的的后台要保持时间  
  35.             }  
  36.             if (context.Request.Form["userID"] != null && context.Request.Form["userID"].ToString() != "")  
  37.             {  
  38.                 userID = int.Parse(context.Request.Form["userID"].ToString());  
  39.             }  
  40.             int i = 0;//计算超时时间(秒)  
  41.             while (true)  
  42.             {  
  43.                 Thread.Sleep(1000);//停留一千毫秒(1秒)  
  44.                 i++;  
  45.                 if (i < SendTime)  
  46.                 {  
  47.                     if (NameStr(userID) != "")  
  48.                     {  
  49.                         context.Response.Write(NameStr(userID));  
  50.                         break;  
  51.                     }  
  52.                 }  
  53.                 if (i == SendTime)  
  54.                 {  
  55.                     context.Response.Write("fail:无数据");  
  56.                     break;  
  57.                 }  
  58.             }  
  59.         }  
  60.         /// <summary>  
  61.         /// 获得用户名  
  62.         /// </summary>  
  63.         /// <param name="userID"></param>  
  64.         /// <returns></returns>  
  65.         private string NameStr(int userID)  
  66.         {  
  67.             string result = string.Empty;  
  68.             string Sqlstr = "select top 1 ID,UserName from AjaxPolling   Order by ID desc";  
  69.             DataSet ds = new DataSet();  
  70.             ds = SQLHelper.Query(Sqlstr, null);  
  71.             if (ds != null)  
  72.             {  
  73.                 if (ds.Tables[0].Rows.Count >= 1)  
  74.                 {  
  75.                     if (int.Parse(ds.Tables[0].Rows[0][0].ToString()) != userID || 0 ==int.Parse(ds.Tables[0].Rows[0][0].ToString()))  
  76.                     {  
  77.                         result = ds.Tables[0].Rows[0][0].ToString() + "," + ds.Tables[0].Rows[0][1].ToString();  
  78.                     }  
  79.                 }  
  80.             }  
  81.  
  82.             return result;  
  83.         }  
  84.         public bool IsReusable  
  85.         {  
  86.             get 
  87.             {  
  88.                 return false;  
  89.             }  
  90.         }  
  91.     }  

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

代码下载:长轮询AJAX之.net实现

原文链接:http://www.cnblogs.com/bluescreen/archive/2013/03/15/2960675.html

责任编辑:林师授 来源: 博客园
相关推荐

2011-05-18 13:28:46

jQueryPHPAJAX

2023-11-28 08:49:01

短轮询WebSocket长轮询

2021-12-29 07:44:50

Dotnet 代码系统

2022-07-14 08:36:28

NacosApollo长轮询

2012-08-01 14:16:27

IBMdW

2022-07-15 19:57:18

Cadence轮询开源

2021-07-07 08:01:51

命令行Dotnet Core控制台

2009-05-20 14:49:16

ibmdwAjaxWeb开发

2021-02-26 12:37:39

WebSocketOkHttp连接

2012-04-27 10:00:43

jQuery插件

2017-08-21 21:00:33

Java长图文

2009-06-26 13:46:13

Struts

2017-10-12 15:34:17

2011-05-24 13:37:16

jQueryAjax

2009-06-18 15:23:49

缓存控制器模式Ajax模式

2012-09-28 10:18:53

IBMdw

2009-08-07 09:57:20

Ajax分页功能

2023-05-10 07:53:08

.Net开发多进程通信方式

2022-04-07 07:51:40

代码结构设计

2021-03-17 08:12:03

架构Dotnet洋葱
点赞
收藏

51CTO技术栈公众号