SpringBoot simply integrates WebSocket

Posted by UnknownPlayer on Wed, 05 Jan 2022 22:46:15 +0100

WebSocket overview

websocket protocol is an application layer protocol based on TCP/IP, which is used to realize full duplex communication between server and client.

The difference between WebSocket and http

The http protocol we usually use is that the client requests the server's data, and then the server responds to the client after receiving the client's request. websocket can not only actively send data to the server, but also actively send data to the client.

WebSocket application scenario

For some businesses waiting for polling query, for example, other people like you and give you a like notification on your client. If it is http protocol, you can only continuously poll the server to see if there are new likes, and if there is a response to the client. This not only wastes bandwidth and resources, but also is not timely. How long you can receive the like notification depends on the time interval of your polling. If you use websocket, when others like you, the server can actively send a message to the client to remind you to add 1 to the number of likes! Save bandwidth and respond in time!
To put it bluntly, in some scenarios where the server needs to actively send requests to the client, use websocket!

Springboot integrates WebSocket

  1. International practice pilot package, in POM XML add the following dependencies. We don't need to specify the version of the jar package. springboot will help us automatically import the jar package suitable for the current version
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
  1. Inject a bean into the configuration class
@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}
  1. Start writing the WebSocketServer class
@Component
@ServerEndpoint("/ws/{token}")
public class WebSocketServer {
    private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * One token per client
     */
    private String token = "";

    private static HashMap<String, Session> map = new HashMap<>();//hashmap is used to save each client. key is the token of each client and value is the session of each client

    /**
     * Connection succeeded
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) {
        LOG.info("New connection: token: {},session id: {},Current connections:{}", token, session.getId(), map.size());
        map.put(token, session);
        this.token = token;

    }

    /**
     * Connection closed
     */
    @OnClose
    public void onClose(Session session) {
        map.remove(this.token);
        LOG.info("Connection closed, token: {},session id: {}!Current connections:{}", this.token, session.getId(), map.size());
    }

    /**
     * Received message
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        LOG.info("Message received:{},Content:{}", token, message);
    }

    /**
     * Connection error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        LOG.error("An error occurred", error);
    }

    /**
     * Mass messaging
     */
    public void sendInfo(String message) {
        for (String token : map.keySet()) {

            Session session = map.get(token);
            try {
                //Get each session and send a message through the session
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                LOG.error("Push message failed:{},Content:{}", token, message);
            }
            LOG.info("Push message:{},Content:{}", token, message);
        }
    }

}

There are several important notes above, which are

@ServerEndpoint("/ws/{token}")
@OnOpen
@OnClose
@OnMessage
@OnError

@ServerEndpoint("url")
This annotation is similar to @ RequestMapping("URL") and is used to map the request path. When accessing ws://ip: port number / url, it will be mapped to the corresponding WebSocketServer class.
@OnOpen
When a websocket connection is created, the annotated method is executed.
@OnClose
When the websocket connection is closed, the annotated method is executed.
@OnMessage
When a message is received, the annotation marked method is executed.
@OnError
When an error occurs, the annotation marked method is executed.
In addition, I also use a map to save the conversation of each client. key is the token of each client and value is the session.
A sendInfo method is written to send messages in groups.
When we need to send messages voluntarily, we can inject this WebSocketServer class in the corresponding service, and then call the sendInfo() method to send the message, as shown below.

Topics: Java Spring Boot websocket