WebSockets

  • Servlet 堆栈和 WebSockets 的集成

  • WebSocket 消息传递,包括原始 WebSocket 交互

  • WebSocket 仿真,例如 SockJS

  • STOMP 协议,用于通过 WebSocket 进行发布-订阅消息传递 See equivalent in the Reactive stack

参考文档的这一部分涵盖对 Servlet 堆栈、包括原始 WebSocket 交互在内的 WebSocket 消息传递、通过 SockJS 的 WebSocket 仿真以及通过 WebSocket 上的子协议以发布-订阅消息传递的形式使用 STOMP 的支持。

This part of the reference documentation covers support for Servlet stack, WebSocket messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and publish-subscribe messaging through STOMP as a sub-protocol over WebSocket.

Introduction to WebSocket

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

The WebSocket protocol, RFC 6455, provides a standardized way to establish a full-duplex, two-way communication channel between client and server over a single TCP connection. It is a different TCP protocol from HTTP but is designed to work over HTTP, using ports 80 and 443 and allowing re-use of existing firewall rules.

WebSocket 交互开始于一个 HTTP 请求,该请求使用 HTTP Upgrade 标头进行升级或(在本例中)切换到 WebSocket 协议。以下示例显示了这种交互:

A WebSocket interaction begins with an HTTP request that uses the HTTP Upgrade header to upgrade or, in this case, to switch to the WebSocket protocol. The following example shows such an interaction:

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 The Upgrade header.
2 Using the Upgrade connection.

服务器不再使用常见的 200 状态代码,而是返回类似以下内容的输出:

Instead of the usual 200 status code, a server with WebSocket support returns output similar to the following:

HTTP/1.1 101 Switching Protocols 1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
1 Protocol switch

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

After a successful handshake, the TCP socket underlying the HTTP upgrade request remains open for both the client and the server to continue to send and receive messages.

WebSocket 工作原理的完整介绍超出了本文的范围。请参见 RFC 6455、HTML5 中的 WebSocket 章节或 Web 上的各种简介和教程。

A complete introduction of how WebSockets work is beyond the scope of this document. See RFC 6455, the WebSocket chapter of HTML5, or any of the many introductions and tutorials on the Web.

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

Note that, if a WebSocket server is running behind a web server (e.g. nginx), you likely need to configure it to pass WebSocket upgrade requests on to the WebSocket server. Likewise, if the application runs in a cloud environment, check the instructions of the cloud provider related to WebSocket support.

HTTP Versus WebSocket

即使 WebSocket 被设计为与 HTTP 兼容且以 HTTP 请求开头,但了解两个协议导致非常不同的体系结构和应用程序编程模型非常重要。

Even though WebSocket is designed to be HTTP-compatible and starts with an HTTP request, it is important to understand that the two protocols lead to very different architectures and application programming models.

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

In HTTP and REST, an application is modeled as many URLs. To interact with the application, clients access those URLs, request-response style. Servers route requests to the appropriate handler based on the HTTP URL, method, and headers.

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

By contrast, in WebSockets, there is usually only one URL for the initial connect. Subsequently, all application messages flow on that same TCP connection. This points to an entirely different asynchronous, event-driven, messaging architecture.

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

WebSocket is also a low-level transport protocol, which, unlike HTTP, does not prescribe any semantics to the content of messages. That means that there is no way to route or process a message unless the client and the server agree on message semantics.

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

WebSocket clients and servers can negotiate the use of a higher-level, messaging protocol (for example, STOMP), through the Sec-WebSocket-Protocol header on the HTTP handshake request. In the absence of that, they need to come up with their own conventions.

When to Use WebSockets

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

WebSockets can make a web page be dynamic and interactive. However, in many cases, a combination of AJAX and HTTP streaming or long polling can provide a simple and effective solution.

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

For example, news, mail, and social feeds need to update dynamically, but it may be perfectly okay to do so every few minutes. Collaboration, games, and financial apps, on the other hand, need to be much closer to real-time.

延迟本身并不是决定因素。如果消息量相对较低(例如,监视网络故障),那么 HTTP 流或轮询可以提供一个有效的解决方案。低延迟、高频率和大容量的结合使 WebSocket 成为最佳案例。

Latency alone is not a deciding factor. If the volume of messages is relatively low (for example, monitoring network failures) HTTP streaming or polling can provide an effective solution. It is the combination of low latency, high frequency, and high volume that make the best case for the use of WebSocket.

另外请记住,在 Internet 上,不受你控制的限制性代理可能会阻止 WebSocket 交互,原因可能是因为它们未配置为传递 Upgrade 标头,也可能是因为它们关闭了看起来空闲的长期连接。这意味着对于防火墙内的内部应用程序,使用 WebSocket 比面向公众的应用程序更容易做出决定。

Keep in mind also that over the Internet, restrictive proxies that are outside of your control may preclude WebSocket interactions, either because they are not configured to pass on the Upgrade header or because they close long-lived connections that appear idle. This means that the use of WebSocket for internal applications within the firewall is a more straightforward decision than it is for public facing applications.