反向 Ajax,第 2 部分 WebSocket(4)
 
- UID
- 1066743
|

反向 Ajax,第 2 部分 WebSocket(4)
暂停长期请求使用 Comet 时有另一个障碍。服务器如何能够在不影响性能的前提下暂停长期请求,然后在服务器事件到达时恢复并完成该请求?
显然,您不能只是保留请求和响应,这会导致线程匮乏和内存消耗过高。除了非阻塞 I/O,暂停长轮询请求还需要一个特定的 API。在 Java 中,Servlet 3.0 规范提供了一个这样的 API(参见本系列的 )。清单 9 展示了一个示例。
清单 9. 通过 Servlet 3.0 定义异步 servlet 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:j2ee="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml
/ns/j2ee/web-app_3.0.xsd">
<servlet>
<servlet-name>events</servlet-name>
<servlet-class>ReverseAjaxServlet</servlet-class>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>events</servlet-name>
<url-pattern>/ajax</url-pattern>
</servlet-mapping>
</web-app>
|
在定义了异步 servlet 后,您可以使用 Servlet 3.0 API 暂停和恢复请求,如下所示清单 10:
清单 10. 暂停和恢复请求1
2
3
4
5
6
7
8
9
| AsyncContext asyncContext = req.startAsync();
// Hold the asyncContext reference somewhere
// Then when needed, in another thread you can resume or complete
HttpServletResponse req =
(HttpServletResponse) asyncContext.getResponse();
req.getWriter().write("data");
req.setContentType([...]);
asyncContext.complete();
|
在 Servlet 3.0 之前,每个容器都曾拥有(目前依然拥有)自己的机制。Jetty 的后续产品就是一个众所周知的示例;Java 中的许多反向 Ajax 库都依赖于 Jetty 的后续产品。这算不上是阻碍,不要求您一定要在 Jetty 容器中运行您的应用程序。API 可以非常智能地检测您正在运行的容器,如果在 Tomcat 或 Grizzly 等其他容器中运行时,则会回退到 Servlet 3.0 API(如果有的话)。这种情况同样适用于 Comet。但是如果您想要充分利用 WebSockets,那么目前别无选择,只能使用特定于容器的功能。
Servlet 3.0 规范尚未公布,但是许多容器已经实现了该 API,因为它是执行反向 Ajax 的标准方式。
结束语WebSockets 是非常强大的反向 Ajax 解决方案,尽管存在一些弊端。WebSockets 目前尚未在所有浏览器上实现,没有反向 Ajax 库的帮助,则无法在 Java 中的服务器端轻松使用它。因为您没有使用标准的请求响应格式,因此您不能依赖于作用域的过滤器链执行操作。Comet 和 WebSockets 要求提供特定于容器的服务器端功能,因此您在使用最新的容器或容器无法扩展时,需要注意这一点。
请继续关注本 的第 3 部分,该部分将探讨 Comet 和 WebSockets 的服务器端的不同 API。还将了解 Atmosphere,即一种反向 Ajax 框架。 |
|
|
|
|
|