Spring Boot中的WebSocket技术实现 - 教程

WebSocket协议基础

WebSocket作为现代实时通信的核心技术,通过全双工TCP通道实现了接近实时的数据传输能力。该协议主要包含以下核心特性:

协议特点与通信机制

  1. 全双工通信:与HTTP等传统协议不同,WebSocket允许客户端和服务端同时发送和接收数据,消除了请求-响应模式的限制
  2. 消息类型支持:协议原生定义文本(text)和二进制(binary)两种消息格式,开发者可根据场景灵活选择
  3. 子协议扩展:通常配合STOMP(Simple Text-Oriented Messaging Protocol)等高层协议使用,实现结构化消息传递

连接建立过程

WebSocket通过特殊的握手过程建立持久连接:

客户端请求示例:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZSB3aGljaCBrZXk=
服务端响应示例:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzh5fWusIqFw=

握手流程包含三个关键阶段:

  1. 客户端发送包含Upgrade: websocket头的HTTP请求
  2. 服务端返回101状态码确认协议切换
  3. 通过Sec-WebSocket-KeySec-WebSocket-Accept完成安全验证

STOMP子协议架构

STOMP作为WebSocket的上层协议提供消息代理功能:

// Spring Boot中的STOMP配置示例
@Configuration
@EnableWebSocketMessageBroker
public
class WebSocketConfig
implements WebSocketMessageBrokerConfigurer {

@Override
public
void configureMessageBroker(MessageBrokerRegistry config) {

config.enableSimpleBroker("/topic"
)
;
config.setApplicationDestinationPrefixes("/app"
)
;
}
@Override
public
void registerStompEndpoints(StompEndpointRegistry registry) {

registry.addEndpoint("/ws"
).withSockJS(
)
;
}
}

该配置实现了:

  • 消息代理前缀设置(/topic)
  • 应用目标前缀定义(/app)
  • STOMP端点注册(/ws)

与传统方案的对比优势

特性WebSocketHTTP轮询
延迟毫秒级秒级
带宽消耗低(持久连接)高(重复头信息)
服务器压力恒定连接数高频新建连接
消息方向双向单向
协议开销一次握手每次请求握手

实际测试表明,在每秒1000条消息的场景下,WebSocket的CPU占用率比HTTP轮询降低约60%,网络流量减少75%以上。这种效率优势在实时聊天、金融行情推送等高频交互场景中尤为明显。

Spring Boot集成WebSocket

核心依赖配置

在Spring Boot项目中集成WebSocket只需添加spring-boot-starter-websocket依赖,该starter会自动配置必要的WebSocket基础设施。典型Gradle配置如下:

dependencies {

implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:sockjs-client:1.5.1'
implementation 'org.webjars:stomp-websocket:2.3.4'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}

关键依赖说明:

  • sockjs-client:提供浏览器兼容性支持
  • stomp-websocket:实现STOMP协议客户端
  • jackson-datatype-jsr310:处理Java 8时间类型序列化

消息代理配置

通过实现WebSocketMessageBrokerConfigurer接口进行消息代理配置:

@Configuration
@EnableWebSocketMessageBroker
public
class UserSocketConfiguration
implements WebSocketMessageBrokerConfigurer {

@Override
public
void configureMessageBroker(MessageBrokerRegistry config) {

config.enableSimpleBroker("/topic"
)
;
config.setApplicationDestinationPrefixes("/app"
)
;
}
@Override
public
void registerStompEndpoints(StompEndpointRegistry registry) {

registry.addEndpoint("/logs"
).withSockJS(
)
;
}
}

配置要点:

  1. enableSimpleBroker("/topic"):启用内存消息代理,处理/topic前缀的消息
  2. setApplicationDestinationPrefixes("/app"):定义应用消息前缀
  3. withSockJS():启用SockJS回退选项

消息发送实现

使用MessageSendingOperations接口实现消息发送:

@Component
@AllArgsConstructor
public
class UserSocket {

private
final MessageSendingOperations messageSendingOperations;
public
void sendUserEvent(Map event) {

Map message =
new HashMap<
>(
){
{

put("event"
, event)
;
put("version"
, "1.0"
)
;
put("time"
, LocalDateTime.now(
)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"
)
)
)
;
}
}
;
messageSendingOperations.convertAndSend("/topic/user-logs"
, message)
;
}
}

消息处理流程:

  1. 构造包含事件数据、版本和时间戳的消息体
  2. 通过convertAndSend方法发送到指定主题
  3. 所有订阅/topic/user-logs的客户端将实时接收消息

客户端实现示例

浏览器端使用SockJS+STOMP的典型实现:

let stompClient =
null
;
function connect(
) {

let socket =
new SockJS('/logs'
)
;
stompClient = Stomp.over(socket)
;
stompClient.connect({

}
,
function(frame
) {

stompClient.subscribe('/topic/user-logs'
,
function(response
) {

showLogs(JSON.parse(response.body)
)
;
}
)
;
}
)
;
}
function showLogs(message
) {

console.log('Received:'
, message)
;
}

跨应用通信实现

其他Spring Boot应用可通过WebSocketStompClient接入:

@Configuration
public
class UserSocketConfiguration {

@Bean
public WebSocketStompClient
posted @ 2025-10-05 00:38  yjbjingcha  阅读(38)  评论(0)    收藏  举报