AJAX長輪詢之DotNet實(shí)現(xiàn)
今天和一個(gè)同事聊到了關(guān)于Web(傳統(tǒng))實(shí)時(shí)通訊的問題,其中包括輪詢、長輪詢、長連接。***同事說長輪詢對(duì)與.net來說比較難以實(shí)現(xiàn)(不使用任何框架)。
首先看一下什么是“長輪詢”!定義如下:
長輪詢:客戶端向服務(wù)器發(fā)送Ajax請求,服務(wù)器接到請求后hold住連接,直到有新消息才返回響應(yīng)信息并關(guān)閉連接,客戶端處理完響應(yīng)信息后再向服務(wù)器發(fā)送新的請求。
優(yōu)點(diǎn):在無消息的情況下不會(huì)頻繁的請求。
缺點(diǎn):服務(wù)器hold連接會(huì)消耗資源。
以上 “長輪詢” 定義是我在網(wǎng)上抄的哦!
那么是不是只要滿足以上所訴的內(nèi)容長輪詢是不是就成立呢?那就嘗試一下!
建立數(shù)據(jù)庫:
- 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方法發(fā)送異步請求,前臺(tái)省了很多事情了!
具體代碼請看:
- <%@ 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請求超時(shí)時(shí)間為60秒
- data: { time: 60, userID: userID }, //參數(shù)time時(shí)間為最多等待(后臺(tái)保持)時(shí)間(60秒無論是否有數(shù)據(jù)立即返回),單位為秒。userID判斷詩句是否為新數(shù)據(jù)的標(biāo)識(shí)
- success: function (data, textStatus) {
- var obj = document.getElementById("NameDisplay");
- //判斷返回成功還是失敗 如果后臺(tái)保持連接的時(shí)間一到并且沒有新數(shù)據(jù)就會(huì)返回fail開頭失敗的數(shù)據(jù)
- 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();//請求后立即發(fā)起AJAX請求
- },
- error: function (XMLHttpRequest, textStatus, errorThrown) {
- //New Error do something
- if (textStatus == "timeout") {
- //超時(shí)間
- SendXHR();
- }
- }
- });
- }
- window.onload = function () {
- SendXHR();
- }
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- </div>
- <div id="NameDisplay">
- </div>
- </form>
- </body>
- </html>
前臺(tái)數(shù)據(jù)請求已經(jīng)準(zhǔn)備好了,接下來看一下后臺(tái)代碼實(shí)現(xiàn)。具體代碼如下:
- 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長輪詢后臺(tái)處理頁面
- /// 主要用于保持連接
- /// 有數(shù)據(jù)返回,無數(shù)據(jù)繼續(xù)保持連接超時(shí)返回
- /// author:bluescreen
- /// Date :2013-03-14
- /// blog:http://www.cnblogs.com/bluescreen/
- /// 請不要關(guān)注代碼編寫規(guī)范等一些問題。這僅僅是一個(gè)DEMO
- /// 還存在諸多問題
- /// </summary>
- public class LongPollingServer : IHttpHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- /*
- context.Response.ContentType = "text/plain";
- context.Response.Write("Hello World");*/
- int SendTime = 0; //最多等待時(shí)間
- int userID = 0; //上一次的用戶ID
- if (context.Request.Form["time"] != null&&context.Request.Form["time"].ToString()!="")
- {
- SendTime =int.Parse(context.Request.Form["time"].ToString());//接收傳來的的后臺(tái)要保持時(shí)間
- }
- if (context.Request.Form["userID"] != null && context.Request.Form["userID"].ToString() != "")
- {
- userID = int.Parse(context.Request.Form["userID"].ToString());
- }
- int i = 0;//計(jì)算超時(shí)時(shí)間(秒)
- 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:無數(shù)據(jù)");
- 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;
- }
- }
- }
- }
以上代碼經(jīng)過測試的確符合 “長輪詢” 的說法,那是不是可以說是長輪詢呢?各位大牛你們怎么看?
代碼下載:長輪詢AJAX之.net實(shí)現(xiàn)
原文鏈接:http://www.cnblogs.com/bluescreen/archive/2013/03/15/2960675.html