zoukankan      html  css  js  c++  java
  • AJAX长轮询之DotNet实现

    今天(2013-03-14)和一个同事聊到了关于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  :2013-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;
                }
            }
        }
    }

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

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

    特别声明:此DEMO仅仅以 “长轮询” 定义来实现,简单解释一下长轮询。我相信大家都会明白,像这种处理方式是不能用于实际的项目的!如果需要请了解Comet其他解决方案!

  • 相关阅读:
    UVA 818 Cutting Chains 切断圆环链 (暴力dfs)
    UVA 211 The Domino Effect 多米诺效应 (回溯)
    UVA225 Golygons 黄金图形(dfs+回溯)
    UVA208 Firetruck 消防车(并查集,dfs)
    UVA11212 EditingaBook ( IDA*搜索)
    UVA 140 Brandwidth 带宽 (dfs回溯)
    uva 1601 poj 3523 Morning after holloween 万圣节后的早晨 (经典搜索,双向bfs+预处理优化+状态压缩位运算)
    UVA10410 TreeReconstruction 树重建 (dfs,bfs序的一些性质,以及用栈处理递归 )
    cdoj 414 八数码 (双向bfs+康拓展开,A*)
    UVA 246 10-20-30 10-20-30游戏 模拟+STL双端队列deque
  • 原文地址:https://www.cnblogs.com/bluescreen/p/2960675.html
Copyright © 2011-2022 走看看