共计 1679 个字符,预计需要花费 5 分钟才能阅读完成。
最近对服务器推送技术比较感兴趣,在网上也看了好些文章,由于每个人理解的不同,实现细节或者语言表达方式不同,本人被各种名词或者技术实现搞的头大,于是自己准备整理下。
首先实现服务器推送技术一直一来是 B / S 应用开发的一块难题,因为是基于 HTTP 协议的,HTTP 协议为无状态,单向性的协议,这种情况导致只有客户端请求,服务器才能被动响应结果,虽然 HTTP 协议的优势是很大的,高效,高伸缩性等。但是有优势自然有不足,譬如我想做个聊天室,这种情况导致服务器无法主动向客户端推送消息,这就有了瓶颈。
…. 于是人们就开始寻找各种解决方案了。
一种就是控制客户端的页面不断的进行 ajax 请求,应该很好实现吧。js 定时器就可以实现,每次请求如果服务器端有更新数据则响应到客户端。但是这会造成服务器的严重压力,如果在线用户数量过多的话,每隔个一两秒请求一次,哪个服务器能受得了,这种肯定不太现实,或者是最无奈的实现方法。
于是出现了 comet,comet 技术是服务器推技术的一个总称,但不是具体实现方式。下面我将会讲两种实现方式,是基于 HTTP 长连接的实现。
第一种叫做长轮询(long-polling) 方式,它同样使用的 ajax, 简单说一下,就是客户端使用 ajax 发送一个请求,服务器端肯定会开启一个线程,这个线程会时时监测要请求的数据是否有变化,如果有变化,则向客户端输出最新消息,并关闭链接,客户端收到消息处理之后,再次向服务器端请求,如此循环,所以叫长轮询,这种实现方式比起上一种自然要好的多了,不需要客户端不断的 ajax 请求,减轻服务器端的一定压力,而且可以算得上是实时的。
另外一种是流方式,这种和长轮询方式挺像,只有一点区别,就是流方式是在客户端请求服务端并建立链接之后,服务器端始终不会关闭链接(直到超时,断电或者其他特殊情况)每次有数据时,就向客户端进行输出,而不像长轮询每次向客户端输出之后,都要关闭链接。
关于长轮询和流方式注意以下:
在长轮询方式下,客户端是在 XMLHttpRequest 的 readystate 为 4(即数据传输结束)时调用回调函数,进行信息处理。当 readystate 为 4 时,数据传输结束,连接已经关闭,长轮询方式 IE、Mozilla FireFox 都支持。而至于流方式,Mozilla Firefox 提供了对流方式的支持,即 readystate 为 3 时(数据仍在传输中),客户端可以读取数据,从而无须关闭连接,就能读取处理服务器端返回的信息。IE 在 readystate 为 3 时,不能读取服务器返回的数据,目前 IE 不支持流方式。
comet 实现瓶颈解决——服务器 servlet 线程阻塞问题
到这里大家可能会想到另外一个问题,那就是客户端每来一个请求,都要在服务器端开一个线程来监测数据是否发生变化,即使数据很长时间内都不会发生改变,这条线程依然在这里阻塞着,资源不能得到释放,线程在这里又没其他事干,如果有过多的用户、过多的线程,自然会造成服务器的资源,内存不足的情况。这是个问题,不过既然有问题,自然有解决方法。目前有两种解决方法,第一种是利用 Tomcat 和 Jetty 这两种开源服务器对 NIO 的支持 代码实现和添加服务器支持可以参考 http://www.ibm.com/developerw…,第二种则是 Java 1.6 出来的 Servlet3.0,Servlet3.0 可以实现真正的异步处理,就是新开一个线程用于处理复杂业务,而 servlet 线程本身则继续往下执行直到结束之后,再返回 servlet 容器,待到另一条线程业务处理完之后,再向客户端输出结果。但是使用 servlet3.0,需要 tomcat7 和以上才支持,servlet3.0 的实现百度就有好多,就不在此多赘述了。只谈理论。。。
参考:http://www.ibm.com/developerw…https://software.intel.com/zh…http://www.itjhwd.com/comet-j…
https://www.cnblogs.com/wodem…【有案例】