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"
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();
}
}
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) { }
}
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 ...
Server messages (e.g. CONNECTED) are immutable, means that they cannot be modified.
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:::
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{}
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 ...");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With