1
votes

I am creating a websocket server that interfaces with a web service endpoint on one side and another which receives web socket connection requests from multiple clients. Here are two approaches that I found:

  1. Implement a web socket configurer and web socket handler as such:

Configurer

@Configuration
@EnableWebSocket
public class TestConfig implements WebSocketConfigurer {
   @Override
   public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(testHandler(), "/testHandler")
           .addInterceptors(new HttpSessionHandshakeInterceptor())
           .withSockJS();
   }

   @Bean
   public WebSocketHandler testHandler() {
       return new TestHandler();
   }

Handler

public class TestHandler extends TextWebSocketHandler {
   @Override
   public void afterConnectionEstablished(WebSocketSession session) throws Exception {
      //Take request params and check if a current subscription to external webservice exists, if yes then directly add this session to a map cache repository with the subscription id as key
      //If it is a new request then add session to a map cache repository and make new subscription to the external webservice
   }

   @Override
   public void handleTextMessage(WebSocketSession session, TextMessage message) {
   }
  1. Configure a message broker endpoint to be subscribed to called /subscribe

    public class TestWebSocketConfig implement WebSocketMessageBrokerConfigurer {
    
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {}
    
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {}
    
    @Override
    public void configureClientInboundChannel(ChannelRegistration arg0) {
        System.out.println("");
    }
    
    @Override
    public void configureClientOutboundChannel(ChannelRegistration arg0) {
    }
    
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
    }
    
    @Override
    public boolean configureMessageConverters(List<MessageConverter> arg0) {
       return true;
    }
    
    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration arg0) {}
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
       registry.addEndpoint("/subscribe").withSockJS();
    }
    

Create controller where websocket clients can communicate with

@Controller
public class SubscriptionController {
@Autowired
private SimpMessagingTemplate template;

@MessageMapping("/subscribe1")
@SendTo("/subscribe")
public void addSubscription(String message) {
    System.out.println("hi");
}

Here is my question, am I misunderstanding somewhere where these two methods I speak of meant to be combined together? I was using a tomcat implementation of websocket before which matches method 1 which gives me easy direct control over sessions as I would like to be able to reuse web service subscriptions to avoid duplicate request from distinct clients and also a single requests may map to more than one subscription requests to the external webservice. Yet it seems method 2 would push all data requests to the same "/subscribe" endpoint and all connected clients would be receiving the same data, which is not what I am trying to accomplish. It also seems like the message broker api is limited as it does not allow me access to the subscribed sessions where I can control which sessions the receiving data will be sent to. I realized I had to switch to spring websocket as I needed built in browser compatibility fallback offered by SockJS and automatic heartbeat function offered by Stomp.js.

1
I guess your question is incomplete - a3.14_Infinity
Sorry my post got cut off :) - ron

1 Answers

1
votes

i think i found my answer, method 1 and 2 can be used side by side but not together. Method 2 is used when i want to implement a message broker that can create multiple channel destinations which many users can subscribe to the same destination. Now the question is how i can check whether i can check the number of subscriptions periodically for each existing destination