Spring WebSocket MessageBrokerRegistry 与 StompEndpointRegistry 配置参数详解
概述
在 Spring Framework 中使用 STOMP over WebSocket 时,需要配置消息代理和 STOMP 端点。MessageBrokerRegistry 用于配置消息代理相关设置,StompEndpointRegistry 用于配置 WebSocket 端点。这两个类通常在一个实现了 WebSocketMessageBrokerConfigurer 接口的配置类中使用。
以下表格详细列出了这两个类的主要配置方法及其参数和说明。
MessageBrokerRegistry 配置参数
MessageBrokerRegistry 用于配置消息代理,包括简单的内存代理或外部代理(如 RabbitMQ、ActiveMQ 等)。
| 方法名 | 参数 | 说明 |
|---|---|---|
enableSimpleBroker() |
String... destinationPrefixes |
启用一个简单的内存消息代理,处理以指定前缀开头的消息目的地(如 "/topic" 或 "/queue")。这是一个轻量级代理,适合开发和测试环境。 |
setApplicationDestinationPrefixes() |
String... prefixes |
设置应用目的地的前缀。客户端发送的消息如果以此前缀开头(如 "/app"),则会被路由到带有 @MessageMapping 注解的控制器方法。 |
setUserDestinationPrefix() |
String prefix |
设置用户目的地的前缀(默认为 "/user")。用于支持用户私有队列,当客户端订阅时,服务器会自动将其转换为唯一的队列名称。 |
enableStompBrokerRelay() |
String... destinationPrefixes |
启用 STOMP 代理中继,连接到外部消息代理(如 RabbitMQ、ActiveMQ)。它可以配置代理的主机、端口、凭据等,适合生产环境。 |
setCacheLimit() |
int cacheLimit |
设置简单代理的缓存限制(消息数量)。仅适用于 enableSimpleBroker() 启用的内存代理。 |
setHeartbeatValue() |
long[] heartbeat |
设置心跳间隔(毫秒)。数组包含两个值:[clientHeartbeat, serverHeartbeat],分别表示客户端和服务器的心跳间隔。 |
setPreservePublishOrder() |
boolean preservePublishOrder |
设置是否保留消息发布顺序(默认为 false)。仅适用于简单代理。 |
注意 :enableStompBrokerRelay() 方法返回一个 StompBrokerRelayRegistration 对象,允许进一步配置外部代理的连接细节(如主机、端口、登录凭据等)。常用链式方法如下:
| 链式方法(StompBrokerRelayRegistration) | 参数 | 说明 |
|---|---|---|
setRelayHost() |
String host |
设置外部代理的主机名(如 "localhost")。 |
setRelayPort() |
int port |
设置外部代理的端口(如 61613)。 |
setClientLogin() |
String login |
设置连接到外部代理的客户端登录名。 |
setClientPasscode() |
String passcode |
设置连接到外部代理的客户端密码。 |
setSystemLogin() |
String login |
设置系统级登录名(用于代理间通信)。 |
setSystemPasscode() |
String passcode |
设置系统级密码。 |
setVirtualHost() |
String virtualHost |
设置虚拟主机(如 "/")。 |
StompEndpointRegistry 配置参数
StompEndpointRegistry 用于注册 STOMP 端点,客户端通过该端点建立 WebSocket 连接。
| 方法名 | 参数 | 说明 |
|---|---|---|
addEndpoint() |
String... paths |
注册一个或多个 STOMP 端点路径(如 "/ws")。客户端将通过这些路径连接到 WebSocket。 |
setAllowedOrigins() |
String... origins |
设置允许的跨域源(CORS)。可以指定具体域名(如 "https://example.com")或使用 "*" 允许所有来源(生产环境不推荐)。 |
setAllowedOriginPatterns() |
String... patterns |
设置允许的跨域源模式,支持通配符(如 "https://*.example.com")。Spring Framework 5.3+ 推荐使用此方法替代 setAllowedOrigins()。 |
withSockJS() |
无 | 启用 SockJS 支持,为不支持 WebSocket 的浏览器提供降级方案(如轮询、长轮询等)。 |
setHandshakeHandler() |
HandshakeHandler handshakeHandler |
设置自定义握手处理器,用于在连接建立前进行身份验证或自定义逻辑。 |
addInterceptors() |
HandshakeInterceptor... interceptors |
添加握手拦截器,可以在连接建立前后执行自定义操作(如验证用户、记录日志)。 |
setAllowedOriginPatterns() |
String... patterns |
同上,用于设置允许的跨域源模式。 |
注意 :addEndpoint() 方法返回一个 StompWebSocketEndpointRegistration 对象,允许链式调用其他配置方法(如 setAllowedOrigins() 或 withSockJS())。
完整配置示例
以下是一个典型的配置类示例,展示了如何同时使用 MessageBrokerRegistry 和 StompEndpointRegistry:
java
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker // 启用基于消息代理的WebSocket
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 启用简单内存代理,处理 "/topic" 和 "/queue" 前缀的消息
registry.enableSimpleBroker("/topic", "/queue");
// 设置应用目的地的前缀为 "/app"
registry.setApplicationDestinationPrefixes("/app");
// 设置用户目的地前缀为 "/user"(可选)
registry.setUserDestinationPrefix("/user");
// 配置心跳:客户端每10000ms发送一次,服务器每10000ms发送一次
registry.setHeartbeatValue(new long[]{10000, 10000});
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 注册端点 "/ws",允许来自 "https://example.com" 的跨域请求,并启用SockJS
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("https://example.com")
.withSockJS();
// 可以注册多个端点
registry.addEndpoint("/ws-alt")
.setAllowedOrigins("*"); // 允许所有来源(仅限开发环境)
}
}
关键注意事项
- 生产环境 :使用
enableSimpleBroker()的内存代理不适合集群部署。建议使用enableStompBrokerRelay()连接外部消息代理(如 RabbitMQ)。 - 安全性 :务必在生产环境中限制
setAllowedOrigins()或setAllowedOriginPatterns()的值,避免使用 "*"。同时考虑使用 TLS(wss://)加密连接。 - 心跳:配置适当的心跳间隔以保持连接活跃,并检测死连接。
- SockJS :如果客户端可能使用旧浏览器,则需要启用
withSockJS(),但会带来额外的开销。 - 用户目的地 :
setUserDestinationPrefix()结合@SendToUser注解可以实现点对点消息发送。