Is there a way to use the facilities provided by Spring to have a webSocket connection without using SockJS and STOMP? I need to implement a proprietary webSocket protocol so I cannot use either one at the moment.
I have implemented/hacked together the solution from the following answer, but it requires me to reimplement things that I feel I should not be worrying about.
I guess my question boils down to: is there a way for me to use the nice features of 2.
(below), specifically the MessageBroker, without using STOMP?
A bit of background:
I need to do the following:
- Be able to inject a reference to my persistence provider in each instance of the websocket handler
- Handle each webSocket session in a separate instance of my handler object
- Re-transmit the messages I receive on one endpoint to multiple clients on a different endpoint.
- Implement my own protocol over a standard Text WebSocket connection.
What I have tried so far is:
- Use javax.websocket, where I can handle each request on a separate instance. However, I need to iterate over the open sessions and retransmit on the ones connected to the correct endpoint. Also, I can't use Spring to inject my persistence provider. This was what I was using so far and it seems too hacky.
I.e. (pseudo-code)
@ServerEndpoint("/trade/{id}")
public String handleMessage(@PathParam(id) String id, webSocketSession session){
if(id.equalsIgnoreCase("foo"){
for(Session s: session.getOpenSessions(){
//do things}
} else if(id.equalsIgnoreCase("bar")){
//do other things
}
}
}
- Use the Spring websocket implementation with
@MessageMapping("/trade")
and@SendTo("/queue/position-updates")
. This requires me to use, as a minimum, STOMP. This would mean breaking other applications in the process, which I can't do at the moment. Also, there is the question of the proprietary protocol I need to implement.
I.e. (pseudo-code)
@MessageMapping("/trade/{id}")
@SendTo("/trades/all")
public Greeting greeting(String message){
//do things, return message
}
- A the moment, I am using the Spring websocket implementation by implementing the WebSocketConfigurer class and registering endpoints. This allows me to have each session in a separate handler class and inject the persistence provider. However, I can't seem to get some of the nice things about Spring working:
- I cannot get the parameter
{id}
from theregistry.addHandler(WebsocketHandlerPool(), "/trade/{id}")
into theWebsocketHandlerPool()
, so I have to parse the path when I create each individualWebsocketHandler
. Ideally, I would like to not have to do this. - I have to implement my own message broker if I don't want to iterate over all the sessions inside the code of the websocket message handler. There is no support (as far as I can tell) for
@MessageMapping
and@SendTo
.
- I cannot get the parameter
I.e. (pseudo-code for handler:)
@Override
public void afterConnectionEstablished(WebSocketSession s){
//parses the String of the Path URL and sets it as a field
idFromSessionPath = getIdFromSessionPath(s);
}
@Override
public String handleTextMessage(WebSocketSession session, TextMessage message
{
If(idFromSessionPath.equals("foo"){
//do things
} else {
//do other things
}
}
(pseudo-code for config)
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
registry.addHandler(threadPool(), "/trade/{id}");
}
@Bean
public WebSocketHandler threadPool(){
return new PerConnectionWebSocketHandler(TradeStreamingHandler.class);
}