Reputation: 1756
I have the following JS functions, which are connecting to a WebSocket over STOMP, and handling the onConnected
events, respectively.
function connect(event) {
username = document.querySelector('#name').value.trim();
if(username) {
usernamePage.classList.add('hidden');
chatPage.classList.remove('hidden');
var socket = new SockJS('/ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, onConnected, onError);
}
event.preventDefault();
}
function onConnected(response) {
console.log(response);
// Subscribe to the Public Topic
stompClient.subscribe('/topic/public', onMessageReceived);
// Tell your username to the server
stompClient.send("/app/chat.addUser",
{},
JSON.stringify({sender: username, type: 'JOIN'})
)
connectingElement.classList.add('hidden');
}
Now the first line of the function onConnected
, it logs the following into the console, which apparently looks like something I could add more data into, from the server side.
{
command: "CONNECTED",
headers: {
"heart-beat": "0,0",
version: "1.1"
},
body: ""
}
I also have an HttpHandshakeInterceptor
which implements HandshakeInterceptor
as follows.
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
attributes.put("sessionId", session.getId());
ServletServerHttpResponse servletResponse = (ServletServerHttpResponse) response;
response.getHeaders().set("KEY","VALUE"); // *** I want this either to be in the response header or the body.
}
return true;
}
The line that has a comment starting with ***
is what I am doing right now with no success. What am I doing wrong? Can I even do this and get some parameters there to the client? If I am doing it wrong, how and where to do it right? (because now I am starting to feel like I am trying to do this in the wrong place)
Upvotes: 1
Views: 1807
Reputation: 1756
Okay. So the following is what I have tried to do, with no success.
public class OutboundMessageInterceptor implements ChannelInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(OutboundMessageInterceptor.class);
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
final StompCommand command = headerAccessor.getCommand();
LOGGER.info("Outbound channel preSend (" + command + ")...");
if (command != null) {
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");
return MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
default:
break;
}
}
return message;
}
}
What this basically does is, intercepting the outbound messages in the server and, if the message is CONNECTED
, it will add some custom header (yes I was trying to add body originally, but for testing purposes I stuck to the header for the time being).
However this method can intercept many STOMP commands, except CONNECTED
. I didn't try to intercept others but there probably should be.
Then I again referred to the STOMP Protocol Spec (thanks to @TimBish for his comment above) and read this statement from there.
Only the SEND, MESSAGE, and ERROR frames MAY have a body. All other frames MUST NOT have a body.
So, it seems like we cannot intercept the messages except for SEND
, MESSAGE
& ERROR
. I presume it is because of the adherence to the protocol spec of Spring's STOMP implementation.
Why I tried doing this was to share some common secret between each client connected and the server, where the secret is determined by the server. Still looking for such implementation.
Upvotes: 3