最近对服务器推送技术比较感兴趣,在网上也看了好些文章,由于每个人理解的不同,实现细节或者语言表达方式不同,本人被各种名词或者技术实现搞的头大,于是自己准备整理下。
首先实现服务器推送技术一直一来是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...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。