启用 STOMP
STOMP over WebSocket 的支持由 spring-messaging 和 spring-websocket 模块提供。一旦引入了这些依赖,你就可以通过 WebSocket 暴露 STOMP 端点。
服务器端配置
通过实现 WebSocketMessageBrokerConfigurer 接口并添加 @EnableWebSocketMessageBroker 注解来开启功能:
java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// /portfolio 是客户端进行 WebSocket 握手时连接的 HTTP URL
registry.addEndpoint("/portfolio");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
// 目的地以 /app 开头的消息将被路由到 @Controller 类中的 @MessageMapping 方法
config.setApplicationDestinationPrefixes("/app");
// 开启简单内存代理。目的地以 /topic 或 /queue 开头的消息将发送到代理
config.enableSimpleBroker("/topic", "/queue");
}
}kotlin
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
// /portfolio 是客户端进行 WebSocket 握手时连接的 HTTP URL
registry.addEndpoint("/portfolio")
}
override fun configureMessageBroker(config: MessageBrokerRegistry) {
// 目的地以 /app 开头的消息将被路由到 @Controller 类中的 @MessageMapping 方法
config.setApplicationDestinationPrefixes("/app")
// 开启简单内存代理
config.enableSimpleBroker("/topic", "/queue")
}
}xml
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/portfolio" />
<websocket:simple-broker prefix="/topic, /queue"/>
</websocket:message-broker>TIP
对于内置的简单代理,/topic 和 /queue 前缀没有特殊含义,仅作为区分发布-订阅与点对点消息的惯例。
客户端连接 (JavaScript)
推荐使用 stomp-js/stompjs 库:
javascript
const stompClient = new StompJs.Client({
brokerURL: 'ws://domain.com/portfolio',
onConnect: () => {
console.log('连接成功!');
// 订阅
stompClient.subscribe('/topic/news', (message) => {
console.log('收到消息:' + message.body);
});
}
});
stompClient.activate();补充教学
1. setApplicationDestinationPrefixes 的作用
当你发送消息到 /app/hello 时,Spring 会分析出 /app 是应用前缀,然后把 /hello 交给对应 Controller 处理。如果不配置这个,所有消息都会直接飞到 Broker 代理手里,而不会经过你的 Java 业务代码。
2. 握手与连接的区别
在使用 STOMP 时,实际发生了两次“握手”:
- HTTP 握手: 客户端请求升级到 WebSocket。
- STOMP 连接: 在 WebSocket 通道开启后,客户端立即发送一个
CONNECT帧,双方确认后状态才变为CONNECTED。
3. SockJS 回退
如果担心环境不支持 WebSocket,只需在配置中加上 .withSockJS():
java
registry.addEndpoint("/portfolio").withSockJS();此时客户端也需要相应使用支持 SockJS 的库进行连接。