一、轮询

  1、轮询(Polling)是一种CPU决策如何提供周边设备服务的方式,又称“程控输入输出”(Programmed I/O)。轮询法的概念是:由CPU定时发出询问,依序询问每一个周边设备是否需要其服务,有即给予服务,服务结束后再问下一个周边,接着不断周而复始。

  2、轮询是基站为终端分配带宽的一种处理流程,这种分配可以是针对单个终端或是一组终端的。为单个终端和一组终端连接分配带宽,实际上是定义带宽请求竞争机制,这种分配不是使用一个单独的消息,而是上行链路映射消息中包含的一系列分配机制。

  3、轮询是基于终端的,带宽的请求总是基于CID,而分配则是基于终端。

  4、简单来说,轮询就是客户端定时去请求服务端,  是客户端主动请求来促使数据更新;

  短轮询的基本思路:

    就是浏览器每隔一段时间向浏览器发送http请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。这种方式实现的即时通信,本质上还是浏览器发送请求,服务器接受请求的一个过程,通过让客户端不断的进行请求,使得客户端能够模拟实时地收到服务器端的数据的变化。

  优点:

    比较简单,易于理解,实现起来也没有什么技术难点。缺点是显而易见的,这种方式由于需要不断的建立http连接,严重浪费了服务器端和客户端的资源。尤其是在客户端,距离来说,如果有数量级想对比较大的人同时位于基于短轮询的应用中,那么每一个用户的客户端都会疯狂的向服务器端发送http请求,而且不会间断。人数越多,服务器端压力越大,这是很不合理的。

    因此短轮询不适用于那些同时在线用户数量比较大,并且很注重性能的Web应用。

  接下来通过一个简单的小例子给大家演示一下:

客户端:

<body>
    <label id="lbPolling"></label>
    <script>
        $(function () {
            //轮询,每隔1秒就请求一次
            setInterval(function () {
                debugger;
                $.get("../Home/lbPolling", function (data) {
                    debugger;
                    $("#lbPolling").html("轮询:" + new Date().toLocaleString());
                });
            }, 1000);
        })
    </script>
</body>

服务端:

/// <summary>
        /// 轮询,只要客户端请求就返回数据
        /// </summary>
        /// <returns></returns>
        public ActionResult lbPolling()
        {
            return Content(DateTime.Now.ToString());
        }

二、长轮询  

下面这一段引用:,讲的蛮好的,这里引用学习一下。

HTTP协议本身有两个“漏洞”,也是现在网络通信中无法避免的。

  1、请求(Request)和答复(Response)之间无法确认其连接状况,可就无法确定其所用的时限了。判断客户端与服务端是否相连的一个标准就是客户端的请求是否能收到服务端的答复,如果收得到,就说明连接上了,即时收到的是服务端错误的通知(比如404 not found)。

  2、在获取到答复(Response)前,都无法知道所需要的数据内容是怎么样的(如果有还跟人家要啥)。

原理:

长轮询就是利用了这两个“漏洞”:服务端收到请求(Request)后,将该请求Hold住不马上答复,而是一直等,等到服务端有信息需要发送给客户端的时候,通过将刚才Hold住的那条请求(Request)的答复(Response)发回给客户端,让客户端作出反应。而返回的内容,那就随便服务端了。

然后,客户端收到答复(Response)后,马上再重新发送一次请求(Request)给服务端,让服务端再Hold住这条连接。周而复始,就实现了从服务端向客户端发送消息的实时通信,客户端向服务端发送消息则依旧利用传统的Post和Get进行。

受Web通信现实情况限制,如果服务端长时间没有消息需要推送到客户端的时候,也不能一直Hold住那条链接,因为很有可能被判定为网关超时等超时情况。所以即使没有消息,每间隔一段时间,服务端也要返回一个答复(Response),让客户端重新请求一个链接。

见过一些人喜欢把每次轮询的断开到下次轮询开始客户端的接收->再请求的行为称之为一次“心跳(Beat)”,也挺贴切的。

要实现真正的实时通信,长轮询的实现并不那么简单,因为每次“心跳”时会产生一个小间隙,这个间隙的时候服务端已经将上一个答复(Response)返回,但还没有接收到客户端的下一次请求(Request)。那么这时候,服务端如果有最新消息,就无法推送给客户端了,所以需要将这些消息缓存起来,等到下一次机会到来的时候再XXOO。

理解:

  1、传统的轮询是前端ajax轮询,每隔一段时间发一个请求,服务器响应后马上关掉连接,但是这种方式明显有很大的开销,所以才有了长轮询,就是响应时间变长了,浏览器(客户端)发送一个请求,服务器hold住连接(就是循环加睡觉,可以到网上找找简单的实现代码),等有消息的时候才返回,当然浏览器的这个连接在这个过程中可以阻塞也可以异步非阻塞,ajax是异步的,等等,你说了这么多我还是不知道为什么长轮询可以当push技术用,和传统的有什么区别,这里说一下,长轮询技术要求服务器一旦发送了响应,客户端必须马上再发一个请求,这就变成了服务器是主动方,所以才说是一种伪push技术。  2、跟轮询一样也是客户端请求服务端,但是服务端并不是即时返回,而是当有内容更新的时候才返回内容给客户端,从流程上讲,可以理解为服务器向客户端推送内容;

  接下来通过一个简单的小例子给大家演示一下:

客户端:

<body>
    <label id="lbLongPolling"></label>
    <script>
        $(function () {
           //长轮询,请求服务端,等到响应了,再次请求
            var SendLongPolling = function () {
                $.get("../Home/LongPolling", function (data) {
                    debugger;
                    $("#lbLongPolling").html("长轮询:" + data);
                    SendLongPolling();
                });
            };
            SendLongPolling();
        })
    </script>
</body>

服务端:

/// <summary>
        /// 长轮询,模拟挂起的操作,服务器每秒会有更新,然后返回给客户端实时数据
        /// </summary>
        /// <returns></returns>
        public ActionResult LongPolling()
        {
            while (true)
            {
                Thread.Sleep(1000);
                return Content(DateTime.Now.ToString());
            }
        }

轮询和长轮询的区别:

轮询:

1:大量耗费服务器内存和宽带资源,因为不停的请求服务器,很多时候 并没有新的数据更新,因此绝大部分请求都是无效请求

2:数据不一定是实时更新,要看设定的请求间隔,基本会有延迟。

长轮询:

1:解决了轮询的两个大问题,数据实时更新;

2:唯一的缺点是服务器在挂起的时候比较耗内存;