关闭

Tomcat如何实现Comet

标签: tomcatcometAJAX
7783人阅读 评论(0) 收藏 举报
分类:

Comet模式是一种服务器端推技术,它的核心思想提供一种能让当服务器端往客户端发送数据的方式。Comet模式为什么会出现?刚开始人们在客户端通过不断自动刷新整个页面来更新数据,后来觉得体验不好又使用了AJAX不断从客户端轮询服务器更新数据,然后是使用Comet模式由服务器端通过长连接推数据。Comet模式能大大减少发送到服务器端的请求从而避免了很多开销,而且它还具备更好的实时性。

如图所示,客户端发送一个请求到服务器,服务器接收了连接后一直保持住连接不关闭;接着客户端发送一个操作报文告诉服务器需要做什么操作,服务器处理完事件1后会给客户端响应,然后处理完事件2后又会给客户端响应;然后客户端继续发送操作报文给服务器,服务器再进行响应。

Comet模式

一般Comet模式需要NIO配合,而在BIO中无法使用Comet模式。在Tomcat内部集成Comet模式的思路也比较清晰,引入了一个CometProcessor接口,此接口只有一个event方法,具体接口代码如下:

public interface CometProcessor extends Servlet{
    public void event(CometEvent event)
        throws IOException, ServletException;
}

而CometEvent则表示Comet相关的事件,它包含四BEGIN, READ, END, ERROR四个事件,分别表示:
① BEGIN,表示请求开始,此时客户端连接已被接收。
② READ,表示可以读取客户端连接,你可以开始读取数据了,读取的过程不会阻塞。
③ END,表示请求结束,此时客户端连接将被断开。
④ ERROR,表示发生了IO异常,一般将会结束此次请求并且连接会被断开。

下面看一个简单的例子:

public class CometServlet extends HttpServlet implements CometProcessor {

    protected ArrayList connections = new ArrayList();

    public void event(CometEvent event) throws IOException, ServletException {
        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();
        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            synchronized (connections) {
                connections.add(response);
            }
        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
            synchronized (connections) {
                connections.remove(response);
            }
        }else if (event.getEventType() == CometEvent.EventType.END) {
            synchronized (connections) {
                connections.remove(response);
            }
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            InputStream is = request.getInputStream();
            byte[] buf = new byte[512];
            do {
                int n = is.read(buf);
                if (n > 0) {
                    System.out.println(new String(buf, 0, n));
                } else if (n < 0) {
                    return;
                }
            } while (is.available() > 0);
        }
    }
}

这个例子中只是简单的客户端连接都接收起来而不做任何处理,并将客户端发送过来的数据输出。很容易理解,在BEGIN事件中接收连接并把响应对象假如到列表中,发送ERROR或END事件时则将响应对象移除,当READ事件时则读取数据并输出。

有了CometProcessor接口后,Tomcat内部就可以识别Comet模式的Servlet了,我们知道Tomcat对请求的处理是管道模式的,所以在Wrapper容器的管道中判断加载的Servlet是否继承了CometProcessor,继承则说明是Comet模式,则使用Comet方式处理。它的处理过程如图,当一个客户端连接到来,被接收器接收后注册到NioChannel队列中,Poller组件不断轮询是否有NioChannel需要处理,如果有则调用前面实例化的Comet模式Servlet,这里主要用到CometProcessor接口的event方法,Poller会将对应的请求对象、响应对象和事件封装成都CometEvent对象并传入event方法。此时即执行event方法的逻辑,完成对不同事件的处理,从而实现了Comet模式。
集成Comet

=======================================

公众号的菜单已分为“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以购买。感谢各位朋友。

为什么写《Tomcat内核设计剖析》

========================================

点击订购作者《Tomcat内核设计剖析》

博主的书

4
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

tomcat 实现comet 配置

在项目开发中,由于需要在首页做一个简单的消息总数推送功能,
  • baby_it
  • baby_it
  • 2014-10-28 17:52
  • 989

Comet HTTP服务器推送框架之Comet4J

Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。
  • tianwei7518
  • tianwei7518
  • 2015-02-26 20:09
  • 4131

Comet实现的新选择

目前最强大的开源Comet解决方案是: Dojo+Jetty Cometd+Jetty Continuation+Bayeux协议一些相关的文档先放在这里,我就不多介绍了,大家都完全有能力读懂。 Jetty的作者,Servlet规范专家组成员Greg Wilkins写的两篇文章: Ajax, Com...
  • mozilla
  • mozilla
  • 2007-06-20 08:42
  • 7573

基于 Asp.Net的 Comet 技术解析

基于 Asp.Net的 Comet 技术解析
  • u010243043
  • u010243043
  • 2015-01-29 16:52
  • 566

Ajax与Comet的介绍与区别

Ajax(Asynchronous JavaScript + XML的简写)可以向服务器请求数据而无需卸载(刷新)页面,带来更好的用户体验。  Ajax技术的核心是XMLHttpRequest对象(简称XHR)。 一、XMLHttpRequest对象 /* 兼容IE早期版本 */...
  • hj7jay
  • hj7jay
  • 2016-04-20 09:31
  • 2026

HTTP长连接(Comet)实现方式示例

<br />昨天看了comet的介绍后,虽然大概知道了comet的原理,不过没实际用过还是不太清楚,于是今天又在网上翻了一下别的网友共享的comet实现http长连接的例子,在 Comet Server Push 技术介绍 一文中分别提到了 ”基于长轮询(long polling)“...
  • HarbinZJU
  • HarbinZJU
  • 2011-03-28 11:18
  • 11012

Comet技术

Comet是一种用于web的技术,能使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和流。 长轮询 长轮询是在打开一条连接以后保持,等待服务器推送来数据再关闭的方式。 iframe流 流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务...
  • shanliangliuxing
  • shanliangliuxing
  • 2012-07-17 14:38
  • 3384

websocket与comet的性能对比

http://chenkangxian.iteye.com/blog/2268133 博客分类:  webjava并发 websocketcomet性能web即时交互  对于comet长连接来说,服务端如有内容需要发送给客户端时,服务端将原...
  • liangxw1
  • liangxw1
  • 2016-03-05 20:06
  • 5595

java web 服务器推送技术 comet实现(原理)

最近研究服务器推送技术,
  • fengge374043291
  • fengge374043291
  • 2014-07-17 09:50
  • 6728
    作者
    https://github.com/sea-boat

    公众号:(内容包括分布式、机器学习、深度学习、NLP、Java深度、Java并发核心、JDK源码、Tomcat内核等等)



    微信:

    打赏作者

    如果您觉得作者写的文章有帮助到您,您可以打赏作者一瓶汽水(*^__^*)

    个人资料
    • 访问:1018660次
    • 积分:13606
    • 等级:
    • 排名:第1100名
    • 原创:320篇
    • 转载:5篇
    • 译文:1篇
    • 评论:342条
    博客专栏
    最新评论