springboot:basic_websocket

Basic Websocket

This is going to build a STOMP based websocket on server site.

  1. Add dependency to POM.XML
  2. Add a EnableWebSocketMessageBroker configuration
  3. Add a controller to handle the web socket package.

Add the following in POM.XML

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

Create a java class that @Configuration and @EnableWebSocketMessageBroker. Here we register an endpoint /my-websocket-endpoint for frontend to connect to. We add the prefix /app as application destination prefix so that when the client send their request, they need to add it in their destination. And we have add a channel topic for client to subscribe.

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/my-websocket-endpoint").withSockJS();
    }

}

We user @MessageMapping to get the client request, and @SendToUser to send respond back to the requested client, or @SendTo to respond to all clients that subscribe to the channel. The server can also send package to the client by using SimpMessagingTemplate.

@Controller
public class GreetingController {
    private final SimpMessagingTemplate simpMessagingTemplate;

    public GreetingController(SimpMessagingTemplate simpMessagingTemplate) {
        this.simpMessagingTemplate = simpMessagingTemplate;
    }

    @MessageMapping("/hello")
    @SendToUser("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }

    @MessageMapping("/helloToAll")
    @SendTo("/topic/greetings")
    public Greeting greetingToAll(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }

    public void broadcastNews() {
        this.simpMessagingTemplate.convertAndSend("/topic/news", new Greeting("This is a news broadcast"));
    }
}

First import sockjs, and stomp.js library.

function connect() {
    var socket = new SockJS('/my-websocket-endpoint');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/user/topic/greetings', function (greeting) {
            console.log(JSON.parse(greeting.body).content);
        });
        stompClient.subscribe('/topic/greetings', function (greeting) {
            console.log(JSON.parse(greeting.body).content);
        });
        stompClient.subscribe('/topic/news', function (greeting) {
            console.log(JSON.parse(greeting.body).content);
        });
    });
}
function disconnect() {
    if (stompClient !== null) {
        stompClient.disconnect();
    }
    setConnected(false);
    console.log("Disconnected");
}

We have mapped /hello to one of our method in the controller. Since we set /app as prefix, we need to do the following:

stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));

We have already setup those callback functions while we subscribe the channels during the connection.

  • The websocket has a default 25 second keep-a-live package.
  • The socket will auto disconnect when the browser/tab is closed.
  • springboot/basic_websocket.txt
  • Last modified: 2021/10/07 12:06
  • by chongtin