对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

WebSockets

本参考文档的这一部分涵盖了对 Servlet 栈的支持,以及 WebSocket 消息传递,包括原始的 WebSocket 交互、通过 SockJS 实现的 WebSocket 仿真,以及在 WebSocket 之上使用 STOMP 子协议进行的发布-订阅消息传递。spring-doc.cadn.net.cn

WebSocket 介绍

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

WebSocket 交互始于一个使用 HTTP Upgrade 头的 HTTP 请求, 以升级(或在此情况下切换)到 WebSocket 协议。以下示例 展示了此类交互:spring-doc.cadn.net.cn

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 连接。

与通常的 200 状态码不同,支持 WebSocket 的服务器会返回类似如下的输出:spring-doc.cadn.net.cn

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

握手成功后,HTTP 升级请求底层的 TCP 套接字将保持打开状态,供客户端和服务器继续发送和接收消息。spring-doc.cadn.net.cn

本文档的范围不包括对 WebSocket 工作原理的完整介绍。 有关详细信息,请参阅 RFC 6455、HTML5 中的 WebSocket 章节,或网上众多的入门指南和教程。spring-doc.cadn.net.cn

请注意,如果 WebSocket 服务器运行在 Web 服务器(例如 nginx)之后,您很可能需要配置该 Web 服务器,使其将 WebSocket 升级请求转发给 WebSocket 服务器。同样,如果应用程序运行在云环境中,请查阅云服务提供商关于 WebSocket 支持的相关说明。spring-doc.cadn.net.cn

HTTP 与 WebSocket

尽管 WebSocket 被设计为与 HTTP 兼容,并以 HTTP 请求开始, 但理解这两种协议会导致截然不同的架构和应用程序编程模型非常重要。spring-doc.cadn.net.cn

在 HTTP 和 REST 中,应用程序被建模为多个 URL。客户端通过访问这些 URL,以请求-响应的方式与应用程序进行交互。服务器根据 HTTP URL、方法和请求头,将请求路由到相应的处理器。spring-doc.cadn.net.cn

相比之下,在 WebSocket 中,通常只有一个用于初始连接的 URL。 随后,所有应用消息都通过该相同的 TCP 连接进行传输。这指向了一种完全不同的异步、事件驱动的消息架构。spring-doc.cadn.net.cn

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

WebSocket 客户端和服务器可以通过 HTTP 握手请求中的 Sec-WebSocket-Protocol 头协商使用更高层的消息协议(例如 STOMP)。如果没有该头信息,它们就需要自行约定通信规范。spring-doc.cadn.net.cn

何时使用 WebSocket

WebSocket 可以使网页变得动态且具有交互性。然而,在许多情况下,结合使用 Ajax 与 HTTP 流式传输或长轮询即可提供一种简单而有效的解决方案。spring-doc.cadn.net.cn

例如,新闻、邮件和社交动态需要动态更新,但每隔几分钟更新一次可能就完全足够了。而协作应用、游戏和金融类应用则需要更接近实时的更新。spring-doc.cadn.net.cn

仅延迟本身并不是一个决定性因素。如果消息量相对较低(例如,监控网络故障),HTTP 流式传输或轮询可以提供一种有效的解决方案。 只有在低延迟、高频率和高吞吐量三者结合的情况下,才最能体现使用 WebSocket 的优势。spring-doc.cadn.net.cn

还需注意的是,在互联网上,您无法控制的限制性代理可能会阻止 WebSocket 通信,原因可能是它们未配置为传递 Upgrade 头部,或者因为它们会关闭看似空闲的长连接。这意味着,对于防火墙内部的应用程序而言,使用 WebSocket 是一个更为直接明确的选择,而对于面向公众的应用程序则不然。spring-doc.cadn.net.cn