如何在Spring Boot应用程序中向STOMP创建的消息添加自定义头?
我试图将自定义头添加到STOMP“CREATED”消息中,该消息由客户端在第一次连接时接收。下面是使用STOMP JavaScript连接到WebSocket的函数:如何在Spring Boot应用程序中向STOMP创建的消息添加自定义头?,spring,spring-boot,websocket,stomp,spring-websocket,Spring,Spring Boot,Websocket,Stomp,Spring Websocket,我试图将自定义头添加到STOMP“CREATED”消息中,该消息由客户端在第一次连接时接收。下面是使用STOMP JavaScript连接到WebSocket的函数: function connect() { socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect('', '', function(frame) { whoami = frame.he
function connect() {
socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect('', '', function(frame) {
whoami = frame.headers['user-name'];
console.log(frame);
stompClient.subscribe('/user/queue/messages', function(message) {
console.log("MESSAGE RECEIVED:");
console.log(message);
showMessage(JSON.parse(message.body));
});
stompClient.subscribe('/topic/active', function(activeMembers) {
showActive(activeMembers);
});
});
}
此函数将以下内容打印到浏览器控制台:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
我想添加自定义标题,因此输出必须如下所示:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
custom-header: "foo"
我的Spring Boot应用程序中有以下WebSocket配置。WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue", "/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat", "/activeUsers")
.withSockJS()
.setInterceptors(customHttpSessionHandshakeInterceptor());
}
...
@Bean
public CustomHttpSessionHandshakeInterceptor
customHttpSessionHandshakeInterceptor() {
return new CustomHttpSessionHandshakeInterceptor();
}
}
我尝试注册“握手接收器”来设置自定义标题,但没有成功。这是“CustomHttpSessionHandshakeInterceptor”:CustomHttpSessionHandshakeInterceptor.java
public class CustomHttpSessionHandshakeInterceptor implements
HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest =
(ServletServerHttpRequest) request;
attributes.put("custom-header", "foo");
}
return true;
}
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Exception ex) { }
}
公共类CustomHttpSessionHandshakeInterceptor实现
握手接受器{
@凌驾
握手前公共布尔值(ServerHttpRequest请求,
ServerHttpResponse响应,
WebSocketHandler wsHandler,
映射属性)引发异常{
if(ServletServerHttpRequest的请求实例){
ServletServerHttpRequest servletRequest=
(ServletServerHttpRequest)请求;
attributes.put(“自定义标题”、“foo”);
}
返回true;
}
握手后公共无效(ServerHttpRequest请求,
ServerHttpResponse响应,
WebSocketHandler wsHandler,
例外情况ex){}
}
我在上找到了这个代码段
有人能解释一下为什么这种方法不起作用吗?在Spring Boot应用程序中,是否有其他方法可以在服务器端为STOMP“CREATED”消息设置自定义头?
谢谢 你是这样试的吗?MessageHeaderAccessor也有一个setHeader方法。
也许太晚了,但迟做总比不做好 服务器消息(如连接的)是不可变的,这意味着它们不能被修改 我要做的是注册一个客户端出站拦截器,通过覆盖preSend(…)方法捕获连接的消息,并使用我的自定义头构建一个新消息
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel)
{
LOGGER.info("Outbound channel pre send ...");
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
final StompCommand command = headerAccessor.getCommand();
if (!isNull(command)) {
switch (command) {
case CONNECTED:
final StompHeaderAccessor accessor = StompHeaderAccessor.create(headerAccessor.getCommand());
accessor.setSessionId(headerAccessor.getSessionId());
@SuppressWarnings("unchecked")
final MultiValueMap<String, String> nativeHeaders = (MultiValueMap<String, String>) headerAccessor.getHeader(StompHeaderAccessor.NATIVE_HEADERS);
accessor.addNativeHeaders(nativeHeaders);
// add custom headers
accessor.addNativeHeader("CUSTOM01", "CUSTOM01");
final Message<?> newMessage = MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
return newMessage;
default:
break;
}
}
return message;
}
并重写方法configureClientOutboundChannel,如下所示
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
log.info("Configure client outbound channel started ...");
registration.interceptors(new CustomOutboundChannelInterceptor());
log.info("Configure client outbound channel completed ...");
}
是的,我尝试使用“MessageHeaderAccessor”,它非常适用于带有STOMP“MESSAGE”命令的消息(在我的例子中,普通消息由Spring的“@MessageMapping”注释的方法处理,并由“SimpMessageTemplate”发送)。问题是如何使用STOMP'CONNECTED'命令为消息添加自定义标题,该命令是在建立WebSocket连接后由服务器发送的?对我来说,这个答案缺少很多支持方面。例如,类应该是什么样子,扩展了哪些类,实现了哪些接口,最后是在何处以及如何注册这个拦截器。如果有这些,我想这将是一个很好的答案。@RomeoSierra我完全同意,这只是一个暗示,而不是一个完整的答案。请看我上面的更新。@TheAlDeal我在
final StompCommand=headerAccessor.getCommand()处得到空值代码>
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
log.info("Configure client outbound channel started ...");
registration.interceptors(new CustomOutboundChannelInterceptor());
log.info("Configure client outbound channel completed ...");
}