Search code examples
springspring-bootwebsocketspring-websocket

I am not receiving WebSocket messages (SimpMessagingTemplate)


I am not able to get my WS working. I wrote this test and it is still failing when I use simpMessagingTemplate but when I use stompSession.send it works. Could anyone help me where I am making mistake?

The problem is NOT in the test PROBABLY, I am not able to make simpMessagingTemplate working in any service.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(MockitoExtension.class)
public class WebSocketSpec {
    @LocalServerPort
    private Integer port;
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    private WebSocketStompClient webSocketStompClient;


@BeforeEach
public void initialize(){
    webSocketStompClient = new WebSocketStompClient(new SockJsClient(List.of(new WebSocketTransport(new StandardWebSocketClient()))));
}

@Test @DisplayName("test subscription to /topic/plcs/connection-status")
void testSubscriptionToPlcConnectionEndpoint() throws Exception{
    CountDownLatch latch = new CountDownLatch(1);

    webSocketStompClient.setMessageConverter(new MappingJackson2MessageConverter());

    StompSession stompSession = webSocketStompClient.connect("ws://localhost:" + port+"/api/ws", new StompSessionHandlerAdapter() {
    }).get(1, TimeUnit.SECONDS);

    stompSession.subscribe("/topic/plcs/connection-status", new StompFrameHandler() {
        @Override
        public Type getPayloadType(StompHeaders stompHeaders) {
            return String.class;
        }

        @Override
        public void handleFrame(StompHeaders stompHeaders, Object o) {
            latch.countDown();
            System.out.println("RECEIVED: "+o);
        }
    });

    //stompSession.send("/topic/plcs/connection-status", "SENT FROM TEST!!!");
    simpMessagingTemplate.convertAndSend("/topic/plcs/connection-status", "SENT FROM TEST!!!");

    if (!latch.await(5, TimeUnit.SECONDS)){
        fail("Message not received");
    }
}
}

My configuration for WS looks like this:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/queue", "/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }
}

Solution

  • So, there are actually two problems ...

    1. first is that you are using wrong messageConvertor (new MappingJackson2MessageConverter() instead of new StringMessageConverter())
    2. the simpMessagingTemplate.convertAndSend("/topic/plcs/connection-status", "SENT FROM TEST!!!"); is fired before the client is subscribed, I have just tried to put there some delay before it with Thread.sleep(500); and it worked.