用 ASP.NET MVC 實現基於 XMLHttpRequest long polling(長輪詢) 的 Comet

來源:互聯網
上載者:User

之前在“反向Ajax,第1部分:Comet介紹”(英文版)文章中學習了“基於 Multipart XMLHttpRequest 的 Comet”的知識,然後用 ASP.NET MVC 實現了一個,詳見用 ASP.NET MVC 實現基於 Multipart XMLHttpRequest 的 Comet。

今天繼續學習了基於 XMLHttpRequest long polling 的 Comet,又用 ASP.NET MVC 實現了一個,在這篇文章中分享一下。

先瞭解一下什麼是XMLHttpRequest long polling?

這是一種推薦的實現Comet的做法,開啟一個到伺服器端的Ajax請求然後等待響應。伺服器端需要一些特定的功能來允許請求被掛起,只要一有事件發生,伺服器端就會在掛起的請求中送迴響應並關閉該請求。然後用戶端就會使用這一響應並開啟一個新的到伺服器端的長生存期的Ajax請求。

This is a recommended method to implement Comet is to open an Ajax request to the server and wait for the response. The server requires specific features on the server side to allow the request to be suspended. As soon as an event occurs, the server sends back the response in the suspended request and closes it. The client then consumes the response and opens a new long-lived Ajax request to the server.

我個人的理解是,看起來就像在Web環境中用戶端能訂閱服務端的事件,伺服器端通過事件去通知用戶端。如果伺服器端用 ASP.NET 來實現,可以利用 .NET 的事件驅動機制,很有意思,下面的範例程式碼將展示這一點。

先看Web前端js代碼:

jQuery(function ($) {
function long_polling() {
$.getJSON('/comet/LongPolling', function (data) {
if (data.d) {
$('#logs').append(data.d + "<br/>");
}
long_polling();
});
}
long_polling();
});

js代碼很簡單,就是一個遞迴調用(調用在callback時進行的),通過jQuery的$.getJSON發起Ajax請求,'/comet/LongPolling' 表示請求的服務端 CometController 的 LongPolling Action 的網址。這裡我們可以看出實現 Comet 的痛點不在 Web 前端,而是在伺服器端。

接下來重點看 Web 服務器 ASP.NET MVC Controller 的代碼。

首先要注意的是為了響應 XMLHttpRequest long polling 請求,我們需要實現一個非同步控制器(AsyncController),如果您對 AsyncController 不熟悉,建議閱讀MSDN上的文章 Using an Asynchronous Controller in ASP.NET MVC 。

先上 Controller 的實現代碼:

(註:該控制器實現的功能是每隔5秒鐘向用戶端發送伺服器當時間)

public class CometController : AsyncController
{
//LongPolling Action 1 - 處理用戶端發起的請求
public void LongPollingAsync()
{
//計時器,5秒種觸發一次Elapsed事件
System.Timers.Timer timer = new System.Timers.Timer(5000);
//告訴ASP.NET接下來將進行一個非同步作業
AsyncManager.OutstandingOperations.Increment();
//訂閱計時器的Elapsed事件
timer.Elapsed += (sender, e) =>
{
//儲存將要傳遞給LongPollingCompleted的參數
AsyncManager.Parameters["now"] = e.SignalTime;
//告訴ASP.NET非同步作業已完成,進行LongPollingCompleted方法的調用
AsyncManager.OutstandingOperations.Decrement();
};
//啟動計時器
timer.Start();
}

//LongPolling Action 2 - 非同步處理完成,向用戶端發送響應
public ActionResult LongPollingCompleted(DateTime now)
{
return Json(new { d = now.ToString("MM-dd HH:mm:ss ") +
"-- Welcome to cnblogs.com!" },
JsonRequestBehavior.AllowGet);
}
}

實現非同步控制器需要繼承 System.Web.Mvc.AsyncController,並將 Action 分解為兩個,比如 Action 叫 LongPolling,則分解為 LongPollingAsync 與 LongPollingCompleted 。LongPollingAsync 接受用戶端請求,並發起非同步作業;非同步作業完成,調用LongPollingCompleted。

AsyncManager.OutstandingOperations.Increment(); 告訴ASP.NET接下來將進行一個非同步作業。

AsyncManager.OutstandingOperations.Decrement(); 告訴ASP.NET非同步作業完成,請調用LongPollingCompleted()方法。

範例程式碼中的非同步作業就是將伺服器目前時間作為參數傳遞給 LongPollingCompleted() 方法,LongPollingCompleted() 擷取伺服器目前時間並傳遞給用戶端,用戶端收到後將之顯示出來,將繼續發起 Ajax 請求 ... 這樣周而復始,實現了基於 XMLHttpRequest long polling 的 Comet。

範例程式碼運行結果如下:

小結

以前覺得 Comet 是很高深的東西,自己動手做了之後,發覺原來沒那麼難。所以,重要的是動手去做!

如果不能在實際項目中去做,那就寫一篇部落格吧!

代碼下載

CometMvcDemo_LongPolling.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.