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

  英文原文:Reverse Ajax, Part 3: Web servers and Socket.IO
  前言

  时至今日,用户期待的是可通过web访问快速、动态的应用。这一文章系列展示了如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用。系列的第1部分介绍了反向Ajax、轮询(polling)、流(streaming)、Comet和长轮询(long polling)。你已经了解了Comet是如何使用HTTP长轮询的,这是可靠地实现反向Ajax的最好方式,因为现有的所有浏览器都提供支持。系列的第2部分说明了如何使用WebSocket来实现反向Ajax,一些代码例子被用来帮助说明WebSocket、FlashSocket、服务器端的约束、请求作用域(request-scoped)服务以及暂停长生存期请求等。

  在本篇文章中,我们深入细节,讨论在web应用中使用不同web容器和API(Servlet 3.0和Jetty Continuations)的Comet和WebSocket,了解如何通过使用诸如Socket.IO一类的抽象库来透明地使用Comet和Websocket。Socket.IO使用功能检测来确定连接是使用WebSocket、Ajax长轮询、Flash还是其他方式来建立。

  前提条件

  理想情况下,要充分体会本文的话,你应该对JavaScrpit和Java有一定的了解。本文中创建的例子是使用Google Guice来构建的,这是一个使用Java编写的依赖注入框架。若要读懂文中所谈内容,你应该要熟悉诸如Guice、Spring或是Pico一类的依赖注入框架的概念。

  若要运行本文中的例子,你还需要最新版本的Maven和JDK(参见参考资料)。

  Comet和WebSocket的服务器端解决方案

  你在第1部分内容中已经了解到了,Comet(长轮询或是流)需要服务器端能够暂停某个请求,并在一个可能的长延迟之后恢复或是完成该请求。第2部分内容描述了服务器端如何使用非阻塞式的I/O功能来处理大量的连接,以及它们只能使用线程来服务请求(每个请求一个线程模式)。你也已经了解到了WebSocket的使用是服务器端依赖的,且并非所有的服务器都支持WebSocket。

  本节内容说明了如果适用的话,那么在Jetty、Tomcat和Grizzly等web服务器上是如何使用Comet和WebSocket的。本文提供的源代码包含了Jetty和Tomcat的一个聊天web应用例子。本节内容还讨论了下面的这些应用服务器:Jboss、Glassfish和WebSphere所支持的API。

  Jetty

  Jetty是一个web服务器,支持Java Servlet 3.0规范、WebSocket和其他的许多集成规范。Jetty:

  1. 功能强大且灵活

  2. 易于嵌入

  3. 支持虚拟主机、会话集群和许多可很容易地通过用于Google App Engine的托管服务的Java代码或是XML来配置的功能。

  核心的Jetty项目由Eclipse Foundation打理。

  从版本6开始,Jetty加入了一个被称作Jetty Continuation(Jetty延续)的异步API,该API允许请求被暂停并在之后被恢复。表1给出了所支持的规范和Jetty的主要版本系列的API之间的一个对照关系。

  表1. Jetty的版本和支持

SupportsJetty 6Jetty 7Jetty 8
Non-blocking I/OXXX
Servlet 2.5XXX
Servlet 3.0 XX
Jetty Continuations (Comet)XXX
WebSockets XX

  若要实现使用Comet的反向Ajax的话,你可以使用Jetty的Continuation API,如清单1所示:

  清单1. 用于Comet的Jetty Continuation API

// 暂停一个来自servlet方法(get、post......)的请求:
protected
void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Continuation continuation
= ContinuationSupport.getContinuation(req);
// 可选的做法,设置超时以避免请求挂起过久
continuation.setTimeout(0);
// 挂起请求
continuation.suspend();
// 保存引用,以备将来另一线程使用
continuations.offer(continuation);
}
// 然后,来自另一个想给客户发送事件的线程:
while (!continuations.isEmpty()) {
Continuation continuation
= continuations.poll();
HttpServletResponse response
=
(HttpServletResponse) continuation.getServletResponse();
// 向响应中写入
continuation.complete();
}

it知识库反向Ajax,第3部分:Web服务器和Socket.IO,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。