首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

反向 Ajax,第 3 部分 Web 服务器和 Socket.IO(2)

反向 Ajax,第 3 部分 Web 服务器和 Socket.IO(2)

TomcatTomcat 可能是最广为人知的 Web 服务器。人们使用它已经很多年了,并且它已作为 Web 容器集成到早期版本的 Jboss 应用服务器中。Tomcat 还可以用作 servlet 规范的参考实现。servlet API 2.5 开始停用 Tomcat,人们开始关注基于非阻塞 I/O(如 Jetty)的替代物。表 2 显示了 Tomcat 两个最新版本支持的规范和 API。
表 2. Tomcat 支持支持Tomcat 6Tomcat 7非阻塞 I/OXXServlet 2.5XXServlet 3.0
XAdvanced I/O (Comet)XXWebSocket


如 表 2 中所示,Tomcat 并不支持 WebSocket;它使用一个与 Jetty Continuation 等效的对等物(叫 Advanced I/O)来支持 Comet。Advanced I/O 是一个包装 NIO 的低级包装器,比优秀的 API 更能促进 Comet 的使用。使用此 API 的应用程序示例相对贪乏,没有几个。清单 3 显示了在聊天 Web 应用程序中用于挂起请求和恢复使用请求的 servlet 示例。您可以在本文里的  中找到完整的 Web 应用程序。
清单 3. Comet 的 Tomcat API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public final class ChatServlet extends HttpServlet
                               implements CometProcessor {

    private final BlockingQueue<CometEvent> events =
         new LinkedBlockingQueue<CometEvent>();

    public void event(CometEvent evt)
        throws IOException, ServletException {

        HttpServletRequest request = evt.getHttpServletRequest();
        String user =
            (String) request.getSession().getAttribute("user");
        switch (evt.getEventType()) {
            case BEGIN: {
                if ("GET".equals(request.getMethod())) {
                    evt.setTimeout(Integer.MAX_VALUE);
                    events.offer(evt);
                } else {
                    String message = request.getParameter("message");
                    if ("/disconnect".equals(message)) {
                        broadcast(user + " disconnected");
                        request.getSession().removeAttribute("user");
                        events.remove(evt);
                    } else if (message != null) {
                        broadcast("[" + user + "]" + message);
                    }
                    evt.close();
                }
            }
        }
    }

    void broadcast(String message) throws IOException {
        Queue<CometEvent> q = new LinkedList<CometEvent>();
        events.drainTo(q);
        while (!q.isEmpty()) {
            CometEvent event = q.poll();
            HttpServletResponse resp = event.getHttpServletResponse();
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/html");
            resp.getWriter().write(message);
            event.close();
        }
    }
}




在 Tomcat 里,异步 servlet 必须实现一个 CometProcessor。对于异步 servlet,Tomcat 并不调用标准 HTTP 方法(doGet 和 doPost 等)。相反,会向                 event(CometdEvent) 方法发送一个事件。在请求到达时,该示例会查看是否为了挂起该请求而使用了一个                GET 方法;不必调用 evt.close() 。如果调用的是一个                POST 方法,则表示用户发送了一个消息,该消息将传播至其他 CometEvent,并且可以调用 evt.close() 来完成请求的传送。在用户端,广播会让所有的长轮询请求来完成消息发送,并且会立即发送另一个长轮询请求来接收下一个事件。
Grizzly 和 GlassfishGrizzly 并不是一个 Web 容器,它更像是一个帮助开发人员构建可伸缩性应用程序的 NIO 框架。它发展为 Glassfish 项目的一部分,但也可以单独或嵌套使用它。Grizzly 提供了充当 HTTP/HTTPS 服务器的部件,还为 Bayeux Protocol、Servlet、HttpService OSGi 和 Comet 等提供部件。Grizzly 支持 WebSocket,并且可以在 Glassfish 中使用它来支持 Comet 和 WebSocket。
Glassfish(Oracle 的应用服务器)是 J2EE 6 规范的参考实现。Glassfish 是一个完整的套件(像 WebSphere 和 Jboss 一样),它用 Grizzly 来支持 NIO、WebSocket 和 Comet。它的模块架构(基于 OSGI)使得更改部件变得非常灵活。表 3 显示了 Glassfish 对 Comet 和 WebSocket 的支持。
表 3. Glassfish 支持支持Glassfish 2Glassfish 3非阻塞 I/OXXServlet 2.5XXServlet 3.0
XCometXXWebSocket
X
Grizzly 的使用并不繁琐,可以在 Java 代码中嵌套使用或直接使用它。人们普遍将它用作一个框架,用它来支持可以嵌套在大型应用程序(如 Glassfish)中的 Comet 和 WebSocket,这提供了 Web 部署功能和 Servlet 规范 API。
查看  中关于 Grizzly 或 Glassfish 中的 WebSocket 和 Comet 示例的链接。因为 Glassfish 使用了 Grizzly,所以两个示例都有效。WebSocket API 与Jetty 中的非常相似,但是 Comet API 更复杂一些。
返回列表