# websocket **Repository Path**: code-org/websocket ## Basic Information - **Project Name**: websocket - **Description**: SpringBoot + WebSocket 实时通知的几种方案 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-01-04 - **Last Updated**: 2025-01-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringBoot + WebSocket 实时通知的几种方案 ## 概念 实时通知是指系统能够在事件发生时立即向用户发送信息,而无需用户主动请求。这种通知方式通常用于需要快速响应的场景,例如聊天应用、在线游戏、金融交易平台等。 **场景** 1. 聊天应用:用户发送消息后,其他在线用户可以立即收到通知,增强互动体验。 2. 在线游戏:游戏状态的变化(如玩家得分、游戏开始等)可以实时推送给所有参与者。 3. 金融交易:股票价格、市场动态等信息可以实时更新,帮助用户做出快速决策。 4. 社交媒体:用户的动态、评论或点赞等信息可以即时通知相关用户,提升用户参与度。 **WebSocket** **WebSocket**是一种在单个[TCP](https://baike.baidu.com/item/TCP/0?fromModule=lemma_inlink)连接上进行[全双工](https://baike.baidu.com/item/全双工/0?fromModule=lemma_inlink)通信的协议。WebSocket通信协议于2011年被[IETF](https://baike.baidu.com/item/IETF/0?fromModule=lemma_inlink)定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被[W3C](https://baike.baidu.com/item/W3C/0?fromModule=lemma_inlink)定为标准。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。 在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 **区分** | **属性** | **HTTP** | **WebSocket** | | ---------------- | ---------------------------------------------------- | ---------------------------------------------------------- | | **通信模式** | 单向通信(客户端请求,服务端响应)。 | 双向通信(客户端和服务端可主动发送消息)。 | | **连接模式** | 每次请求都会建立和断开 TCP 连接(短连接)。 | 建立后保持连接,支持长连接。 | | **传输协议** | 基于 TCP 的请求-响应模式。 | 基于 TCP 的全双工通信协议。 | | **实时性** | 需要轮询或长轮询才能实现实时通信,效率较低。 | 原生支持实时通信,延迟低。 | | **协议头** | 每次请求都需要携带完整的 HTTP 头信息,开销较大。 | 连接建立后头信息较少,数据包开销小。 | | **状态保持** | 无状态协议(需要额外机制如 Cookie、Session)。 | 连接保持状态,天然支持有状态通信。 | | **适用场景** | 适合网页浏览、文件下载等请求响应模式场景。 | 适合聊天、游戏、实时推送等需要频繁消息交互的场景。 | | **带宽消耗** | 较高,每次请求都会重复发送头信息。 | 较低,仅初次建立连接时发送头信息。 | | **复杂性** | 简单易用,广泛支持,成熟的工具链。 | 相对复杂,需要额外的客户端和服务端实现支持。 | | **连接建立方式** | 使用 HTTP 协议直接发送请求。 | 使用 HTTP 协议进行握手(升级协议),然后切换为 WebSocket。 | | **标准化支持** | 标准化程度高,支持广泛的 HTTP 方法(GET、POST 等)。 | 标准化程度较高,但需要特定的客户端和服务端支持。 | | **数据格式** | 通常是文本(JSON、HTML)或二进制(文件)。 | 支持文本和二进制消息。 | | **安全性** | 使用 HTTPS 加密。 | 使用 WSS 加密,安全性等同于 HTTPS。 | **特点** - 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10[字节](https://baike.baidu.com/item/字节/0?fromModule=lemma_inlink)(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的[掩码](https://baike.baidu.com/item/掩码/0?fromModule=lemma_inlink)。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。 - 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。 - 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。 - 更好的二进制支持。Websocket定义了[二进制](https://baike.baidu.com/item/二进制/0?fromModule=lemma_inlink)帧,相对HTTP,可以更轻松地处理二进制内容。 - 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持[压缩](https://baike.baidu.com/item/压缩/0?fromModule=lemma_inlink)等。 - 更好的压缩效果。相对于[HTTP压缩](https://baike.baidu.com/item/HTTP压缩/0?fromModule=lemma_inlink),Websocket在适当的扩展支持下,可以沿用之前内容的[上下文](https://baike.baidu.com/item/上下文/0?fromModule=lemma_inlink),在传递类似的数据时,可以显著地提高压缩率。 ## 快速入门 * [SpringBoot + ServerEndpointExporter](./quickstart/serverendpointexporter-quickstart.md) * [SpringBoot + WebSocketConfigurer](./quickstart/websocketconfigurer-quickstart.md) * [SpringBoot + WebSocketMessageBrokerConfigurer](./quickstart/websocketmessagebrokerconfigurer-quickstart.md) * ServerEndpointExporter 、WebSocketConfigurer、WebSocketMessageBrokerConfigurer 区别 | **属性** | **WebSocketConfigurer** | **WebSocketMessageBrokerConfigurer** | **ServerEndpointExporter** | | ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | **功能** | 提供完全自定义的 WebSocket 配置,支持直接定义端点与处理逻辑。 | 提供基于 STOMP 协议的高级消息代理功能,支持主题订阅、消息广播、点对点通信等。 | 基于 JSR-356 标准实现 WebSocket,快速定义端点和处理逻辑。 | | **配置** | 手动实现接口 `WebSocketConfigurer`,需要定义 `registerWebSocketHandlers` 方法并配置端点。 | 实现 `WebSocketMessageBrokerConfigurer` 接口,使用 `@EnableWebSocketMessageBroker` 注解启用消息代理。 | 通过 Spring 提供的 `ServerEndpointExporter` 自动扫描 `@ServerEndpoint` 注解定义的端点。 | | **灵活性** | 高度灵活,可通过编程方式完全控制 WebSocket 的行为,例如跨域配置、握手拦截器、自定义协议。 | 提供高级的消息代理功能,但灵活性不如 `WebSocketConfigurer`,更适合标准化场景。 | 灵活性较低,依赖于注解的方式定义端点和逻辑,适合轻量级的实时通信需求。 | | **适用场景** | 适合需要直接处理 WebSocket 连接、消息和协议的复杂场景,或者需要自定义握手、连接逻辑的场景。 | 适合需要基于主题和订阅的复杂消息广播系统,例如聊天室、通知系统等。 | 适合轻量级 WebSocket 应用,快速实现实时通信,例如简单的聊天或推送服务。 | | **端点定义** | 手动注册端点,并通过 URL 映射到 `WebSocketHandler` 进行逻辑处理。 | 使用消息代理端点(例如 `/topic` 和 `/queue`),客户端通过 STOMP 连接到消息代理服务。 | 通过 `@ServerEndpoint` 注解定义端点,URL 与逻辑绑定直接通过注解声明。 | | **建议** | 如果需要完全自定义 WebSocket 功能,选择 **`WebSocketConfigurer`**。 | 如果需要基于 STOMP 的消息代理功能,选择 **`WebSocketMessageBrokerConfigurer`**。 | 如果仅需快速实现轻量级实时通信功能,选择 **`ServerEndpointExporter`**。 | | **协议支持** | 不内置任何特定协议支持。可以通过实现自定义 `HandshakeInterceptor` 或 `WebSocketHandler` 来扩展协议支持。 | 内置支持 STOMP 协议。可以通过实现 `ChannelInterceptor` 或自定义消息转换器来扩展 STOMP 消息格式和处理逻辑。 | 遵循 JSR-356 标准,不内置特定应用层协议支持。可以通过实现 `Encoder` 和 `Decoder` 来扩展消息编码和解码逻辑,从而支持自定义协议。 | ## 高级进阶 * [SpringBoot + ServerEndpointExporter高级进阶](./advanced/serverendpointexporter-advanced.md) ## 参考连接 [Pub/Sub Messaging](https://docs.spring.io/spring-data/redis/reference/redis/pubsub.html) - Spring Data Redis 发布订阅 [https://juejin.cn/post/7244407068098560037](https://juejin.cn/post/7244407068098560037)