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

反向 Ajax,第 4 部分 Atmosphere 和 CometD(1)

反向 Ajax,第 4 部分 Atmosphere 和 CometD(1)

简介本  文章向您展示如何使用反向 Ajax 技术开发事件驱动的 Web 程序。 介绍了 Reverse Ajax、轮询、流、Comet 和长轮询。 介绍了如何使用 WebSocket 实现 Reverse Ajax,还讨论了使用 Comet 和 WebSocket 的 Web 服务器的限制。 探讨了当您需要支持多个服务器或提供一个用户可以自己的服务器上部署的独立 Web 应用程序时,您实现自己的 Comet 或 WebSocket 通信系统的过程中会遇到的一些困难。即使客户端上的 JavaScript 代码很简单,您仍然需要一些异常处理、重新连接和确认功能。在服务器端,由于缺少全局 API 以及一些 Web 服务器 API,导致需要使用附带抽象功能的框架。第 3 部分还讨论了Socket.IO。
在本文中,您将了解 Atmosphere 和 CometD,它们是用于 Java 服务器的最有名的开源反向 Ajax 库。
您可以下载本文使用的 。
先决条件在理想的情况下,如果想最大限度地利用本文,您应该了解 JavaScript 和 Java。要运行本文中的示例,则需要使用最新版的 Maven 和 JDK(参阅 )。
Atmosphere 框架Atmosphere 是一种 Java 技术框架,它提供了一个通用 API,以便使用许多 Web 服务器(包括 Tomcat、Jetty、GlassFish、Weblogic、Grizzly、JBossWeb、JBoss 和 Resin)的 Comet 和 WebSocket 特性。它支持任何支持 Servlet 3.0 Specification 的 Web 服务器。在本系列文章展示的所有框架中,Atmosphere 支持的服务器最多。
Atmosphere 可以针对 Comet,Atmosphere 检测本机服务器 API 并切换回 Servlet 3.0 的运行时环境。或者将退回到 "托管" 异步模式(但不具有 Jetty Continuations 的可伸缩性),这也适用于 Comet。Atmosphere 已面市两年多了,仍然处于积极开发阶段。它被应用于大型 Web 应用程序中,比如 JIRA,这是最有名的问题追踪器之一。图 1 显示了 Atmosphere 框架。
图 1. Atmosphere 的构架视图 Atmosphere 框架由 Atmosphere 运行时所组成,为各种不同 Web 服务器解决方案和标准提供了一个通用 API。在运行时上面,客户端可以通过设置 servlet 并使用 Google Web Toolkit (GWT) 来访问 API 和反向 Ajax 特性。或者,您还可以使用 Jersey,这是一种用于实现 JSR-311(JAX-RS 规范)的框架。因此,可以使用注释的方式将 Atmosphere 用于更多其它的 REST 场景中。配置您选择的模块之后,就可以通过实现一些类(本文稍后进行讨论)来访问 Atmosphere 运行时。您还可以随意使用所提供的插件,添加对集群、消息传递、依赖注入的支持。如果您正在使用一个 Web 框架(Wicket、Struts 或 Spring MVC),您可以通过使用 Atmosphere 的 MeteorServlet 明确添加对反向 Ajax 的支持。该 servlet 展示了Meteor 对象,可以在控制器和服务中检索该对象,以便挂起或重新开始请求。
Atmosphere 的优势仍然在于服务器端:它提供了一个标准化 API,该 API 包含与 WebSockets 或 Comet 进行通信的所有不同的解决方案和方法。Atmosphere 没有使用客户端和服务器之间通信的协议,如 Socket.IO 和 CometD。这两个库均提供了客户端 JavaScript 和服务器端 servlet,使用特定的协议(用于握手、消息收发、确认和心跳的协议)进行通信。Atmosphere 的目标是在服务器端提供一个通用的通信信道。如果需要使用特定的协议,比如 Bayeux(CometD 使用的协议),则必须在 Atmosphere 中开发您自己的 “处理程序”。CometD 插件可以满足您的需求:它利用 Atmosphere 的 API 来挂起和重新开始请求,并通过使用 Bayeux 协议来委托 CometD 类来管理 CometD 通信。
Atmosphere 提供了一个 jQuery 客户端库,该库可以使连接设置变得更容易,它能够自动检测可以使用的最佳传输协议(WebSockets 或 CometD)。Atmosphere 的 jQuery 插件的用法与 HTML5 WebSockets API 相似。首先要连接到服务器,注册一个回调来接收消息,然后再放入一些数据。
本文所提供的  中包含了一个 Atmosphere 样例,该样例直接将处理程序用于 Atmosphere servlet。客户端代码始终保持不变;与本  第 1 部分、第 2 部分、第 3 部分文章中所用的代码相同(都位于使用 Comet 长轮询的聊天样例代码中)。您还可以使用 Atmosphere 的 jQuery 插件,但这并不是必需的,因为 Atmosphere 不强迫使用任何通信协议。强烈建议您查看 Atmosphere 项目中的其他示例,特别是那些使用 JSR-311 注释 (Jersey) 的示例。它们确实简化了处理程序的编写。
清单 1 显示了 Atmosphere 处理程序的接口。
清单 1. AtmosphereHandler 接口
1
2
3
4
5
6
7
public interface AtmosphereHandler<F, G> {
    void onRequest(AtmosphereResource<F, G> resource)
        throws IOException;
    void onStateChange(AtmosphereResourceEvent<F, G> event)
        throws IOException;
    void destroy();
}




onRequest 方法接收到来自客户端的所有请求,并决定是否挂起或重新开始请求(或不执行任何操作)。每次挂起或重新开始一个请求、发送一条广播或者出现超时,都会通过 onStateChange 方法发送和接收一个事件。
清单 2 中显示了 Comet 聊天应用程序的 onRequest 方法的实现。
清单 2. AtmosphereHandler 接口 - onRequest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Broadcaster broadcaster =
        BroadcasterFactory.getDefault().lookup(
        DefaultBroadcaster.class, ChatHandler.class.getName(), true);
broadcaster.setScope(Broadcaster.SCOPE.APPLICATION);
resource.setBroadcaster(broadcaster);
HttpServletRequest req = resource.getRequest();
String user = (String) req.getSession().getAttribute("user");
if (user != null) {
    if ("GET".equals(req.getMethod())) {
        resource.suspend(-1, false);
    } else if ("POST".equals(req.getMethod())) {
        String cmd = req.getParameter("cmd");
        String message = req.getParameter("message");
        if ("disconnect".equals(cmd)) {
            close(resource);
        } else if (message != null && message.trim().length() > 0) {
            broadcaster.broadcast("[" + user + "] " + message);
        }
    }
}




典型的惯例是挂起 GET 请求,并使用 POST 请求发送消息。收到消息后,会向所有在广播装置内注册的资源进行广播。注意,该示例未向 HttpServlet 输出流方面写入任何内容。广播或挂起操作只发送其他实现方法接收的事件,如 清单 3 中所示:
清单 3. AtmosphereHandler 接口 - onStateChange
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Broadcaster broadcaster =
    BroadcasterFactory.getDefault().lookup(
        DefaultBroadcaster.class, ChatHandler.class.getName(), true);
// Client closed the connection.
if (event.isCancelled()) {
    close(event.getResource());
    return;
}
try {
    String message = (String) event.getMessage();
    if (message != null) {
        PrintWriter writer =
            event.getResource().getResponse().getWriter();
        writer.write(message);
        writer.flush();
    }
} finally {
    if (!event.isResumedOnTimeout()) {
        event.getResource().resume();
    }
}




现在您需要一个可正常运转的 Comet 聊天应用程序。简言之,重要的 Atmosphere 概念是:代表连接的资源对象,以及负责触发资源事件并决定挂起或重新开始请求的事件的广播装置。注意,这只是一个 Comet 示例。想要能够使用 WebSocket 和 Comet,则需要使用一个客户端库,以及一个更复杂的处理程序。
表 1 下表概述了使用 Atmosphere 框架的利弊。
表 1. Atmosphere 的利弊利弊如果您必须在无法控制的多个 Web 服务器中部署一个 Web 应用程序。同时因为 Atmosphere 支持使用多台 Web 服务器,所以它是让应用程序的反向 Ajax 特性正确发挥其作用的更好的选择。
当您需要在原始的反向 Ajax 通信上使用通用 API,如果没有任何已定义好的协议,那么您可能想要开发或扩展协议。
缺少有关 Atmosphere 的架构、项目、概念和 API 的文档,如果您需要研究源代码或分析提供的示例,这些文档对您会很有帮助。与其他框架的简单 API(如 Socket.IO 和 ometD)相比,该 API 的技术性更强,虽然有时有些难懂。即使用了 Atmosphere 注释,有些名称和属性仍然具有很强的技术性。
尽管在服务器端有出色的抽象功能,但没有良好的客户端库,也没有协议,所以其他所有功能都留待开发人员来开发。如果您需要使用高级的超时检测、确认、回退和跨域等功能,特别是在移动设备上使用这些功能时,目前的库太过于简单,无法满足大型、可伸缩 Web 应用程序的需要。在这种情况下,CometD 更可靠一些;它使用了一个可用来激活某些控制流和错误检测的通信协议,CometD 中提供了所有这些功能。如果您需要额外的特性,使用 CometD JavaScript 客户端和 Atmosphere CometD 插件是一个很不错的替代方案。
返回列表