WebSockets

本参考文档部分涵盖了对Servlet堆栈的支持,包括原始WebSocket交互、通过SockJS进行WebSocket仿真以及通过STOMP作为WebSocket上的子协议进行发布-订阅消息。

WebSocket简介

WebSocket协议,RFC 6455,提供了一种标准化的方式,在单个TCP连接上建立全双工的双向通信通道,用于客户端和服务器之间的通信。它是一种不同于HTTP的TCP协议,但设计为在HTTP上运行,使用端口80和443,并允许重用现有的防火墙规则。

WebSocket交互始于使用HTTP请求,该请求使用HTTP Upgrade头部来升级或在这种情况下切换到WebSocket协议。以下示例展示了这样的交互:

GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket (1)
Connection: Upgrade (2)
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
1 Upgrade头部。
2 使用Upgrade连接。

具有WebSocket支持的服务器返回类似以下内容而不是通常的200状态代码:

HTTP/1.1 101 Switching Protocols (1)
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
1 协议切换

成功握手后,HTTP升级请求下的TCP套接字保持打开状态,以便客户端和服务器继续发送和接收消息。

WebSocket工作原理的完整介绍超出了本文档的范围。请参阅RFC 6455、HTML5的WebSocket章节或网络上的许多介绍和教程。

请注意,如果WebSocket服务器运行在Web服务器(例如nginx)后面,您可能需要配置它以将WebSocket升级请求传递给WebSocket服务器。同样,如果应用程序在云环境中运行,请查看与WebSocket支持相关的云提供商的说明。

HTTP与WebSocket对比

尽管WebSocket旨在与HTTP兼容并以HTTP请求开始,但重要的是要理解这两种协议导致非常不同的架构和应用程序编程模型。

在HTTP和REST中,应用程序被建模为许多URL。客户端通过访问这些URL以请求-响应方式与应用程序交互。服务器根据HTTP URL、方法和头部将请求路由到适当的处理程序。

相比之下,在WebSocket中,通常只有一个URL用于初始连接。随后,所有应用程序消息都在同一TCP连接上流动。这指向了完全不同的异步、事件驱动、消息传递架构。

WebSocket还是一种低级传输协议,与HTTP不同,它不规定消息内容的语义。这意味着除非客户端和服务器就消息语义达成一致,否则无法路由或处理消息。

WebSocket客户端和服务器可以通过HTTP握手请求上的Sec-WebSocket-Protocol头部协商使用更高级别的消息传递协议(例如STOMP)。如果没有这样做,它们需要制定自己的约定。

何时使用WebSockets

WebSockets可以使网页变得动态和交互式。然而,在许多情况下,AJAX和HTTP流或长轮询的组合可以提供简单有效的解决方案。

例如,新闻、邮件和社交动态需要动态更新,但每隔几分钟更新一次可能完全可以。另一方面,协作、游戏和金融应用需要更接近实时。

仅仅延迟不是决定因素。如果消息量相对较低(例如,监视网络故障),HTTP流或轮询可以提供有效的解决方案。低延迟、高频率和高消息量的组合使WebSocket的使用成为最佳选择。

还要记住,在互联网上,您无法控制的限制性代理可能会阻止WebSocket交互,要么是因为它们未配置为传递Upgrade头部,要么是因为它们关闭看似空闲的长连接。这意味着对于防火墙内部应用程序而言,使用WebSocket比面向公众的应用程序更为直接。