Spring MVC 3.2 预览:实时更新技术

工程 | Rossen Stoyanchev | 2012 年 5 月 8 日 | ...

最后更新于 2012 年 11 月 5 日 (Spring MVC 3.2 RC1)

在上一篇博文中,我介绍了 Spring MVC 3.2 中基于 Servlet 3 的新异步支持,并讨论了长时运行请求。第二个非常重要的异步处理动机是浏览器接收实时更新的需求。示例包括浏览器聊天、股票报价、状态更新、实时体育赛事结果等。诚然,并非所有示例对延迟的敏感度都一样,但它们都有相似的需求。

在标准的 HTTP 请求-响应语义中,浏览器发起请求,服务器发送响应,这意味着服务器在收到浏览器的请求之前无法发送新信息。已经出现了几种方法,包括传统轮询长轮询HTTP 流式传输,最近我们还有WebSocket协议。

传统轮询

浏览器不断发送请求以检查新信息,服务器每次都立即响应。这适用于可以在合理稀疏的时间间隔内进行轮询的场景。例如,邮件客户端可以每 10 分钟检查一次新邮件。它很简单,而且有效。然而,当新信息必须尽快显示时,这种方法变得效率低下,在这种情况下,轮询必须非常频繁。

长轮询

浏览器不断发送请求,但服务器在有新信息要发送之前不会响应。从客户端的角度来看,这与传统轮询相同。从服务器的角度来看,这与长时运行请求非常相似,并且可以使用第一部分中讨论的技术进行扩展。

响应可以保持打开多久?浏览器设置为 5 分钟超时,而代理等网络中间设备可能更早超时。因此,即使没有新信息到达,长轮询请求也应该定期完成,以允许浏览器发送新请求。这个IETF 文档建议使用 30 到 120 秒之间的超时值,但实际使用的值可能取决于您对分隔浏览器和服务器的网络中间设备的控制程度。

长轮询可以大大减少接收信息更新所需的请求数量,同时保持低延迟,尤其是在新信息以不规则的时间间隔可用时。然而,更新越频繁,它就越接近传统轮询。

HTTP 流式传输

浏览器向服务器发送请求,服务器在有信息要发送时响应。然而,与长轮询不同的是,服务器保持响应打开状态,并继续发送到达的更多更新。这种方法消除了轮询的需要,但它也更显著地偏离了典型的 HTTP 请求-响应语义。例如,客户端和服务器需要就如何解释响应流达成一致,以便客户端知道一个更新在哪里结束,另一个更新在哪里开始。此外,网络中间设备可能会缓存响应流,这会阻碍该方法的意图。这就是为什么长轮询在今天更常用的原因。

WebSocket 协议

浏览器向服务器发送 HTTP 请求以切换到 WebSocket 协议,服务器通过确认升级来响应。此后,浏览器和服务器可以通过 TCP 套接字双向发送数据帧。

WebSocket 协议旨在取代轮询的需要,并特别适用于需要高频在浏览器和服务器之间交换消息的场景。初始的 HTTP 握手确保 WebSocket 请求可以通过防火墙。然而,挑战也很显著,因为大多数已部署的浏览器不支持 WebSockets,并且在穿越网络中间设备方面存在进一步的问题

WebSockets 围绕文本或二进制消息的双向交换。它导致了一种与 RESTful、基于 HTTP 的架构截然不同的方法。实际上,在 WebSockets 之上还需要另一种协议,例如 XMPP、AMQP、STOMP 或其他协议,至于哪一个(或哪些)将占主导地位,还有待观察。

WebSocket 协议已由 IETF 标准化,而 WebSocket API 正在由 W3C 标准化最后阶段。已经出现了一些 Java 实现,包括 Jetty 和 Tomcat 等 servlet 容器。Servlet 3.1 规范可能会支持初始 WebSocket 升级请求,而单独的JSR-356将定义一个基于 Java 的 WebSocket API。

回到 Spring MVC 3.2,Servlet 3 异步功能可用于长时运行请求和 HTTP 流式传输,Filip Hanik 将这些技术称为“客户端 AJAX 调用的服务器版本”。至于 WebSockets,Spring 3.2 中还没有支持,但很可能会包含在 Spring 3.3 中。您可以关注SPR-9356以获取更新。

下一篇博文将转向示例代码,并更详细地解释新的 Spring MVC 3.2 功能。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有