一、简介
在Asp.net MVC实现的Comet推送的原理很简单。
服务器端:接收到服务器发送的AJAX请求,服务器端并不返回,而是将其Hold住,待到有东西要通知客户端时,才将这个请求返回。
客户端:请求异步Action,当接收到一个返回时,立即又再发送一个。
缺点:会长期占用一个Asp.net处理线程。但相比于轮询,其节省了带宽。
示例:
新建一个Controller如下:
//Comet服务器推送控制器(需设置NoAsyncTimeout,防止长时间请求挂起超时错误) [NoAsyncTimeout, SessionState(SessionStateBehavior.ReadOnly)] public class CometController : AsyncController //需要继承自异步的AsyncController { ////// 异步方法,处理客户端发起的请求 /// public void IndexAsync() { AsyncManager.OutstandingOperations.Increment(); AsyncManager.Parameters["info"] = "怎么了"; AsyncManager.OutstandingOperations.Decrement(); } ////// 当异步线程完成时向客户端发送响应 /// /// 数据封装对象 ///public ActionResult IndexCompleted(string info) { return Json(info, JsonRequestBehavior.AllowGet); } }
随便找一个页面,通过AJAX请求这一个异步Action:
AJAX测试
上面的示例,如果你在Action上下一个断点,会不停的看到断点在循环。说明异步客户端不停地在推送。当然这个示例仅仅是说明推送的原理。
二、应用
应用:监控服务器上的一个txt文件,当有变化时,推送内容到客户端。
//Comet服务器推送控制器(需设置NoAsyncTimeout,防止长时间请求挂起超时错误) [NoAsyncTimeout, SessionState(SessionStateBehavior.ReadOnly)] public class CometController : AsyncController //需要继承自异步的AsyncController { ////// 异步方法,处理客户端发起的请求 /// public void IndexAsync() { AsyncManager.OutstandingOperations.Increment(); FileSystemWatcher FSW = new FileSystemWatcher(); FSW.Filter = "123.txt"; //仅仅监控123.txt文件 FSW.Path = Server.MapPath(@"/"); //设置监控路径 FSW.EnableRaisingEvents = true; //启动监控 //FileSystemWatcher暂时有个多次触发的问题,但与本推送示例无关,故不解决 FSW.Changed += (object source, FileSystemEventArgs e) => { AsyncManager.Parameters["info"] = System.IO.File.ReadAllText(Server.MapPath(@"/123.txt"),System.Text.Encoding.Default); ; AsyncManager.OutstandingOperations.Decrement(); }; } ////// 当异步线程完成时向客户端发送响应 /// /// 数据封装对象 ///public ActionResult IndexCompleted(string info) { return Json(info, JsonRequestBehavior.AllowGet); } }
更多流逼的功能,留着读者自由发挥。