问题描述
我正在尝试将自定义标头添加到STOMP'CREATED'消息中,该消息在第一次连接时由客户端接收.这是使用STOMP JavaScript连接到WebSocket的函数:
I'm trying to add custom headers to the STOMP 'CREATED' message, which is received by client at the first connection. Here is the function which connects to the WebSocket using STOMP JavaScript:
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);
});
});
}
此功能将以下内容输出到浏览器的控制台:
This function prints the following to the browser's console:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
我想添加自定义标头,因此输出必须类似于:
And i want to add custom header so output must look like:
body: ""
command: "CONNECTED"
headers: Object
heart-beat: "0,0"
user-name: "someuser"
version: "1.1"
custom-header: "foo"
我的Spring Boot应用程序中具有以下WebSocket配置.
WebSocketConfig.java
I have the following WebSocket configuration in my Spring Boot app.
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();
}
}
我试图注册'HandshakeInterceptor'来设置自定义标头,但是没有用.这是"CustomHttpSessionHandshakeInterceptor":
CustomHttpSessionHandshakeInterceptor.java
I have tried to register the 'HandshakeInterceptor' to set custom header, but it didn't work. Here is '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) { }
}
我在 https://dzone.com/articles/上找到了此代码段spring-boot-based-websocket
有人可以向我解释为什么这种方法行不通吗?还有另一种方法可以在Spring Boot应用程序的服务器端将自定义标头设置为STOMP'CREATED'消息吗?
谢谢!
I have found this code snippet at https://dzone.com/articles/spring-boot-based-websocket
Can someone explain me why this approach does not work? Is there another way to set custom headers to the STOMP 'CREATED' message at server side in Spring Boot application?
Thanks!
推荐答案
也许为时已晚,但总比没有好...
Maybe it's too late, but better late than never ...
服务器消息(例如CONNECTED)是不可变的,这意味着它们不能被修改.
Server messages (e.g. CONNECTED) are immutable, means that they cannot be modified.
我要做的是注册一个客户端出站拦截器,并通过覆盖preSend(...)方法捕获连接的消息,并使用我的自定义标头构建一条新消息.
What I would do is register a client outbound interceptor and trap the connected message by overriding the preSend(...) method and build a new message with my custom headers.
@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;
}
@UPDATE :::
所需的接口称为ChannelInterceptor
,要注册自己的实现,您需要添加@Configuration
带注释的类
The interface needed is called ChannelInterceptor
and to register your own implementation you need to add @Configuration
annotated class
@Configuration
public class CustomMessageBrokerConfig extends WebSocketMessageBrokerConfigurationSupport
implements WebSocketMessageBrokerConfigurer{}
并如下覆盖方法configureClientOutboundChannel
and override a method configureClientOutboundChannel as below
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
log.info("Configure client outbound channel started ...");
registration.interceptors(new CustomOutboundChannelInterceptor());
log.info("Configure client outbound channel completed ...");
}
这篇关于如何在Spring Boot应用程序中将自定义标头添加到STOMP CREATED消息中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!