Reputation: 15439
I have to add support for a custom WebSocket subprotocol (so not STOMP) in a Spring Boot application, but I'm having a very hard time understanding what I need to provide and what Spring already has.
This is how far I got:
@Configuration
@EnableWebSocket
public class WebSocketAutoConfiguration implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(this.webSocketHandler(), new String[]{endpointUrl});
}
@Bean
public WebSocketHandler webSocketHandler() {
ExecutorSubscribableChannel clientInboundChannel = new ExecutorSubscribableChannel();
ExecutorSubscribableChannel clientOutboundChannel = new ExecutorSubscribableChannel();
SubProtocolWebSocketHandler subProtocolWebSocketHandler = new SubProtocolWebSocketHandler(clientInboundChannel, clientOutboundChannel);
subProtocolWebSocketHandler.addProtocolHandler(new SubProtocolHandler() {
public List<String> getSupportedProtocols() {
return Collections.singletonList("custom-protocol");
}
public void handleMessageFromClient(WebSocketSession session, WebSocketMessage<?> message, MessageChannel outputChannel) throws Exception {
session.sendMessage(new TextMessage("some message"));
}
public void handleMessageToClient(WebSocketSession session, Message<?> message) throws Exception {
}
public String resolveSessionId(Message<?> message) {
return UUID.randomUUID().toString();
}
public void afterSessionStarted(WebSocketSession session, MessageChannel outputChannel) throws Exception {
System.out.println("SESSION STARTED");
}
public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus, MessageChannel outputChannel) throws Exception {
session.close();
System.out.println("SESSION ENDED");
}
});
return subProtocolWebSocketHandler;
}
}
This works, in the sense that handleMessageFromClient
does get triggered on a web socket message, but I fail to understand the purpose of MessageChannel outputChannel
and handleMessageToClient
.
Is it possible to get the PerConnectionWebSocketHandler
semantics with SubProtocolWebSocketHandler
?
The documentation around this is basically non-existent e.g. the docs for handleMessageToClient
say:
Handle the given {@link Message} to the client associated with the given WebSocket session.
Well, fantastic. And the STOMP implementations are mind-boggling, so they're not very usable as a guideline.
Any example, broad steps or anything, really, would be much appreciated.
Upvotes: 6
Views: 4924
Reputation: 15439
Turns out it is exceptionally easy. No need to mess with SubProtocolWebSocketHandler
at all. The only requirement is that the provided WebSocketHandler
implements SubProtocolCapable
.
public class CustomHandler implements WebSocketHandler, SubProtocolCapable {
...
}
That's all. To make a PerConnectionWebSocketHandler
, it's enough to simply extend it and implement SubProtocolCapable
:
public class CustomHandler extends PerConnectionWebSocketHandler implements SubProtocolCapable {
...
}
Upvotes: 4