zoukankan      html  css  js  c++  java
  • 用 ASP.NET MVC 实现基于 XMLHttpRequest long polling(长轮询) 的 Comet(转)

    轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。 
    优点:后端程序编写比较容易。 
    缺点:请求中有大半是无用,浪费带宽和服务器资源。 
    实例:适于小型应用。


    长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。 
    优点:在无消息的情况下不会频繁的请求,耗费资源小。 
    缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。 
    实例:WebQQ、Hi网页版、Facebook IM。

    长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。 
    优点:消息即时到达,不发无用请求;管理起来也相对方便。 
    缺点:服务器维护一个长连接会增加开销。 
    实例:Gmail聊天


    Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。 
    优点:实现真正的即时通信,而不是伪即时。 
    缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙。 
    实例:网络互动游戏。

    出处:https://www.cnblogs.com/dudu/archive/2011/10/17/mvc_comet_long_polling.html

    之前在“反向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

  • 相关阅读:
    linux tcp调优
    nginx 代理http配置实例
    nginx代理socket tcp/udp
    C++对象数组初始化
    《大型网站技术架构》读书笔记
    内核空间、用户空间和虚拟地址(转)
    集群——LVS理论(转)
    Linux服务器集群系统(一)(转)
    从一个开发的角度看负载均衡和LVS(转)
    ubuntu下允许root用户ssh远程登录
  • 原文地址:https://www.cnblogs.com/smileberry/p/9059354.html
Copyright © 2011-2022 走看看