Search code examples
javaspringspring-bootrabbitmqspring-websocket

Spring: send message to websocket clients


I'm building a webchat with Spring Boot, RabbitMQ and WebSocket as POC, but I'm stucked a the last point: WebSockets
I want my ws clients to connect to a specific endpoint, like /room/{id} and when a new message arrives, I want the server to send the response to clients, but I searched for something similar and didn't found.

Currently, when the message arrives, I process it with RabbitMQ, like

container.setMessageListener(new MessageListenerAdapter(){
            @Override
            public void onMessage(org.springframework.amqp.core.Message message, Channel channel) throws Exception {
                log.info(message);
                log.info("Got: "+ new String(message.getBody()));
            }
        });

what I would like is, instead log it , I want to send it to the client, for example: websocketManager.sendMessage(new String(message.getBody()))


Solution

  • Ok, I think I got it, for everyone who needs it, here is the answer:

    first, you need to add WS dependencies to the pom.xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-messaging</artifactId>
    </dependency>
    

    create a WS endpoint

    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            // the endpoint for websocket connections
            registry.addEndpoint("/stomp").withSockJS();
        }
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableSimpleBroker("/");
    
            // use the /app prefix for others
            config.setApplicationDestinationPrefixes("/app");
        }
    
    }
    

    Note: I'm using STOMP, so the clients should connect like this

    <script type="text/javascript">
        $(document).ready(function() {
            var messageList = $("#messages");
            // defined a connection to a new socket endpoint
            var socket = new SockJS('/stomp');
            var stompClient = Stomp.over(socket);
            stompClient.connect({ }, function(frame) {
                // subscribe to the /topic/message endpoint
                stompClient.subscribe("/room.2", function(data) {
                    var message = data.body;
                    messageList.append("<li>" + message + "</li>");
                });
    
            });
        });
    </script>
    

    Then, you can simply wire the ws messenger on your components with

    @Autowired
    private SimpMessagingTemplate webSocket;
    

    and send the message with

    webSocket.convertAndSend(channel, new String(message.getBody()));