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其他解決方案!

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM