Comet:Jquery+asp.net實現http長串連(LongPoll)

來源:互聯網
上載者:User

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="JqueryAjaxLongPoll.aspx.cs" Inherits="JqueryAjaxLongPoll" %>

<!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">
    <title>無標題頁</title>
    <script type="text/javascript" src="script/jquery-1.2.6.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            $("#Button1").bind("click",{btn:$("#Button1")},function(evdata){
                $.ajax({
                    type:"POST",
                    url:"JqueryAjaxLongPoll.aspx",
                    dataType:"json",
                    timeout:10000,
                    data:{ajax:"1",time:"10000"},
                    success:function(data,textStatus){
                            //alert("ok!");
                            evdata.data.btn.click();
                    },
                    complete:function(XMLHttpRequest,textStatus){
                            if(XMLHttpRequest.readyState=="4"){
                                alert(XMLHttpRequest.responseText);
                            }
                    },
                    error: function(XMLHttpRequest,textStatus,errorThrown){
                            //$("#ajaxMessage").text($(this).text()+" out!")
                            alert("error:"+textStatus);
                            if(textStatus=="timeout")
                                evdata.data.btn.click();
                    }
                });
            });

            /*$("#ajaxMessage").ajaxStart(function(){
                $(this).text("準備建立請求.readyState0:");
            });
            $("#ajaxMessage").ajaxSend(function(evt, request, settings){
                $(this).text("開始請求,準備發送資料.readyState1:"+request.readyState);
            });
            $("#ajaxMessage").ajaxComplete(function(event,request, settings){
                if(request.status==200)
                    $(this).text("請求完成.readyState4:"+request.readyState);
            });
            $("#ajaxMessage").ajaxStop(function(){
                $(this).text("請求結束.");
            });*/
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input id="Button1" type="button" value="AjaxLongPoll" />
        <label id="ajaxMessage"></label>
    </div>
    </form>
</body>
</html>

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;

public partial class JqueryAjaxLongPoll : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.Form["ajax"] == "1")
        {
            //Response.End();
            int time = Convert.ToInt32(Request.Form["time"]);
            DateTime date1 = DateTime.Now.AddMilliseconds((double)time);
            bool ready = false;
            while (Response.IsClientConnected)
            {
                Thread.Sleep(3000);
                if (DateTime.Compare(date1, DateTime.Now) < 0)
                {
                    Response.End();
                    break;
                }
                //ready = true;
                if (ready)
                {
                    Response.Write("SetValue('" + DateTime.Now.ToString() + "')");
                    //Response.Flush();
                    Response.End();
                    break;
                }
                else
                {

                }
            }
        }
        else
        {
            if (!Page.IsPostBack)
            {

            }
        }
    }
}

對代碼的說明:利用jquery,很方便的就能實現ajax,上面設定了ajax的timeout時間,由於設定了timeout將會造成不能保持長串連,到了時間ajax自動會報“逾時”的錯誤,也就是會調用error方法,此時textStatus=="timeout",timeout後重新進行ajax請求。伺服器接受ajax請求的時候,會接收一個逾時時間的值,逾時的情況下伺服器端的處理也立即停止。當用戶端成功擷取返回結果時,也會立即進行新的ajax請求,如此迴圈。

為什麼要設定用戶端的ajax逾時值呢?因為伺服器為了保持請求(阻塞請求),必須有一個無限迴圈,迴圈的結束條件就是擷取到了返回結果,如果用戶端關閉了(用戶端瀏覽器的關閉不會發訊息給伺服器),伺服器無法知道用戶端已經關了,這個請求沒必要處理下去了。最終會造成資源過度浪費,只要用一個折中的辦法,限制逾時時間。

可以不必設定用戶端ajax的逾時時間,但進行請求的時候傳遞一個逾時值給伺服器,伺服器在處理的時候,如果逾時時間到了的話,還沒有用戶端需要的結果,這時傳遞一個逾時資訊給用戶端,用戶端接收到了此資訊,根據情況重新進行ajax請求。XMLHttpRequest沒有逾時的參數,Jquery用window.setTimeout自己封裝的(到了定時時間運行逾時處理方法,和XMLHttpRequest結束方法)。可以根據這個思路來改變一下,IBM上介紹的LONG POLL好像也是這樣的。

$(document).ready(function(){
            $("#Button1").bind("click",{btn:$("#Button1")},function(evdata){
                $.ajax({
                    type:"POST",
                    url:"JqueryAjaxLongPoll.aspx",
                    dataType:"json",
                    data:{ajax:"1",time:"6000000"},
                    success:function(data,textStatus){
                            //成功
                            if(data.success=="1"){
                                //用戶端處理
                                //...
                                ///重新請求
                                evdata.data.btn.click();
                            }
                            //逾時
                            if(data.success=="0"){
                                evdata.data.btn.click();
                            }
                    },
                    complete:function(XMLHttpRequest,textStatus){
                            if(XMLHttpRequest.readyState=="4"){
                                alert(XMLHttpRequest.responseText);
                            }
                    },
                    error: function(XMLHttpRequest,textStatus,errorThrown){
                            //$("#ajaxMessage").text($(this).text()+" out!")
//                            alert("error:"+textStatus);
//                            if(textStatus=="timeout")
                                evdata.data.btn.click();
                    }
                });
            });

後台代碼變更後:
if (Request.Form["ajax"] == "1")
        {
            int time = Convert.ToInt32(Request.Form["time"]);
            DateTime date1 = DateTime.Now.AddMilliseconds((double)time);
            bool ready = false;
            while (Response.IsClientConnected)
            {
                Thread.Sleep(3000);
                if (DateTime.Compare(date1, DateTime.Now) < 0)
                {
                    Response.Write("{success:'0'}");
                    Response.End();
                    break;
                }
                //此處進行請求處理,有結果了置ready = true
                //ready = true;
                if (ready)
                {
                    Response.Write("{success:'1'}");
                    Response.End();
                    break;
                }
            }
        }
        else
        {
            if (!Page.IsPostBack)
            {

            }
        }

上面的方法應該就可以滿足要求了,具體的逾時時間可以根據情況來設定。這也是我根據IBM上介紹的“server push”思路,來實現了其中的一種,也不知道有沒有問題,還請大家多多賜教。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.