title: Spring websockets without STOMP and SockJs but with message broker and routing support
body: <p>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.</p>
  
  <p>I have implemented/hacked together the solution from the <a href="https://stackoverflow.com/questions/27158106/websocket-with-sockjs-spring-4-but-without-stomp">following answer</a>, but it requires me to reimplement things that I feel I should not be worrying about.</p>
  
  <p>I guess my question boils down to: is there a way for me to use the nice features of <code>2.</code>(below), specifically the MessageBroker,  without using STOMP?</p>
  
  <p>A bit of background:</p>
  
  <p>I need to do the following:</p>
  
  <ul>
  <li>Be able to inject a reference to my persistence provider in each instance of the websocket handler</li>
  <li>Handle each webSocket session in a separate instance of my handler object</li>
  <li>Re-transmit the messages I receive on one endpoint to multiple clients on a different endpoint.</li>
  <li>Implement my own protocol over a standard Text WebSocket connection.</li>
  </ul>
  
  <p>What I have tried so far is:</p>
  
  <ol>
  <li>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.</li>
  </ol>
  
  <p>I.e. (pseudo-code)</p>
  
  <pre><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
    }
   }
  }
  </code></pre>
  
  <ol start="2">
  <li>Use the Spring websocket implementation with <code>@MessageMapping("/trade")</code> and <code>@SendTo("/queue/position-updates")</code>. 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.</li>
  </ol>
  
  <p>I.e. (pseudo-code)</p>
  
  <pre><code>@MessageMapping("/trade/{id}")
  @SendTo("/trades/all")
  public Greeting greeting(String message){
      //do things, return message
  }
  </code></pre>
  
  <ol start="3">
  <li>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:
  
  <ul>
  <li>I cannot get the parameter <code>{id}</code> from the <code>registry.addHandler(WebsocketHandlerPool(), "/trade/{id}")</code> into the <code>WebsocketHandlerPool()</code>, so I have to parse the path when I create each individual <code>WebsocketHandler</code>. Ideally, I would like to not have to do this.</li>
  <li>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 <code>@MessageMapping</code> and <code>@SendTo</code>.</li>
  </ul></li>
  </ol>
  
  <p>I.e. (pseudo-code for handler:)</p>
  
  <pre><code>@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
      }
  }
  </code></pre>
  
  <p>(pseudo-code for config)</p>
  
  <pre><code>@Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry  registry){
      registry.addHandler(threadPool(), "/trade/{id}");
  }
  
  @Bean
  public WebSocketHandler threadPool(){
      return new PerConnectionWebSocketHandler(TradeStreamingHandler.class);
  
  }
  </code></pre>