Spring中能否为STOMP CONNECTED帧添加自定义头?
Spring STOMP CONNECTED帧自定义头问题解答
是否可以为STOMP CONNECTED帧添加自定义头?
默认情况下不行。Spring的StompSubProtocolHandler在将CONNECT_ACK类型的SiMP消息转换为STOMP CONNECTED帧时,会忽略所有非协议标准的头信息,所以通过ChannelInterceptor.preSend()为CONNECT_ACK消息添加的自定义头不会被包含在最终发送的CONNECTED帧中。
这种设计的原因
- 遵循STOMP协议规范:STOMP协议对CONNECTED帧的头有明确规定,仅要求包含
session、version、heart-beat等标准字段。Spring的实现严格对齐协议,避免引入非标准头导致不同客户端出现兼容性问题。 - 内部消息定位:CONNECT_ACK是Spring WebSocket内部用于确认连接建立的信号,并非设计用来传递业务自定义数据的载体,因此转换过程中仅保留协议所需的核心信息,过滤自定义头。
绕过限制的方法
方法1:自定义StompSubProtocolHandler子类
重写handleMessageToClient方法,手动将SiMP消息中的自定义头添加到CONNECTED帧中:
public class CustomStompSubProtocolHandler extends StompSubProtocolHandler { @Override protected void handleMessageToClient(Message<?> message, StompHeaderAccessor stompHeaderAccessor, Session session) { if (StompCommand.CONNECTED.equals(stompHeaderAccessor.getCommand())) { // 从SiMP消息头中提取自定义字段,添加到STOMP原生头 String customHeader = message.getHeaders().get("X-Custom-Header", String.class); if (customHeader != null) { stompHeaderAccessor.addNativeHeader("X-Custom-Header", customHeader); } } super.handleMessageToClient(message, stompHeaderAccessor, session); } }
然后在WebSocket配置中替换默认的处理器:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureWebSocketTransport(WebSocketTransportRegistration registration) { // 替换为自定义的SubProtocolHandler registration.setSubProtocolHandlers(Collections.singletonList(new CustomStompSubProtocolHandler())); } // 其他WebSocket消息代理配置... }
方法2:直接在CONNECT_ACK生成阶段设置原生头
在生成CONNECT_ACK消息的逻辑中,直接通过StompHeaderAccessor设置STOMP原生头,而非通过ChannelInterceptor添加SiMP消息头。例如在自定义的握手处理器或连接确认逻辑中:
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECTED); accessor.setSessionId(sessionId); accessor.addNativeHeader("X-Custom-Header", "custom-value"); // 构建并发送CONNECT_ACK消息 Message<byte[]> connectedMessage = MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders()); clientOutboundChannel.send(connectedMessage);
内容的提问来源于stack exchange,提问作者Xavier Dury
相关产品推荐
相关产品推荐

