用 ASP.NET MVC 实现基于 XMLHttpRequest long polling(长轮询) 的 Comet

39 篇文章 1 订阅
10 篇文章 0 订阅

之前在“反向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();
} http://

//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。

示例代码运行结果如下:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值