Tomcat如何实现Comet

原创 2016年12月15日 16:37:19

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

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

博主的书

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Comet HTTP服务器推送框架之Comet4J

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

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

昨天看了comet的介绍后,虽然大概知道了comet的原理,不过没实际用过还是不太清楚,于是今天又在网上翻了一下别的网友共享的comet实现http长连接的例子,在 Comet Server Push...

用COMET技术实现WEB实时推送应用(转)

http://www.blogjava.net/JAVA-HE/archive/2009/04/13/265249.html  demo:http://www.blogjava.net/Files/...

Comet HTTP服务器推送框架之icomet

icomet 是一个使用 C++ 语言开发的支持百万并发连接的 comet 服务器, 使用了 libevent 网络库. 支持并发连接数高, 内存占用少, 性能优越. 支持的浏览器和操作系统平台包括:...

java 使用comet4j向客户端主动推送例子

1.准备工作: 1、下载comet4j.js 2、下载comet4j-tomcat7.jar  这个现在只支持tomcat6和7两个版本  一定要对应上了,我这边测试的  在tomcat8下面是用co...
  • ntotl
  • ntotl
  • 2016年07月01日 19:03
  • 9057

Comet框架:Comet4J

Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。 下面网址可以...

Java自定义注解的实现

注解是Java 1.5引入的,目前已经被广泛引用于各种Java框架,如Hibernate,Spring等。首先介绍三个Java内置的注解: 1. @Override,重写(覆盖)注解,当我们想要重写...
  • mhady
  • mhady
  • 2016年06月15日 23:27
  • 368

Java反射学习总结(3)——反射的基本操作

方法的反射主要由下面两个步骤完成:第一步先通过Class类的基本API获取到某一个方法,第二部通过method.invoke(对象,参数列表)函数实现反射 package reflectTest; ...
  • mhady
  • mhady
  • 2016年06月15日 21:33
  • 535

使用Tomcat实现基于iframe streaming的Comet聊天室

这是一个基于Comet实现的聊天室Demo,功能类似于QQ群聊。聊天过程中如果有新想消息,那么就需要服务器推送消息到浏览器,所以这里可以使用Comet技术。 Comet一般有两种实现方式:长轮询(lo...

tomcat 实现comet 配置

在项目开发中,由于需要在首页做一个简单的消息总数推送功能,
  • baby_it
  • baby_it
  • 2014年10月28日 17:52
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Tomcat如何实现Comet
举报原因:
原因补充:

(最多只允许输入30个字)