WebSockets

  • Servlet 堆栈和 WebSockets 的集成

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

  • WebSocket 仿真,例如 SockJS

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

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

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

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

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 套接字保持打开状态,以便客户端和服务器继续发送和接收消息。 WebSocket 工作原理的完整介绍超出了本文的范围。请参见 RFC 6455、HTML5 中的 WebSocket 章节或 Web 上的各种简介和教程。 请注意,如果 WebSocket 服务器在 Web 服务器(例如 nginx)后运行,则可能需要对其进行配置,以将 WebSocket 升级请求传递到 WebSocket 服务器。同样,如果应用程序在云环境中运行,请查看云提供商有关 WebSocket 支持的说明。

HTTP Versus WebSocket

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

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

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

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

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

When to Use WebSockets

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

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

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

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