From today on, roll up your sleeves and follow me


Tip: if you have any questions please contact private, below the source code address, please take it yourself

preface

Using Spring Boot makes it very easy and fast to set up projects, so we don’t have to worry about compatibility between frameworks, applicable versions, etc. We can use anything we want, just add a configuration.


Tip: The following is the body of this article, the following cases for reference

I. Technical introduction

1. What is WebSocket?

Two, the use of steps

1. Import maven libraries

The code is as follows (example) :

	 	<parent>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-parent</artifactId>
	        <version>2.41.</version> <relativePath/> </parent> <dependencies> <! Websocket dependency --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>LATEST</version> </dependency> </dependencies>Copy the code

2. Example of using WebSocket

WebSocket configuration class:

package com.hyh.websocket.config;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/** * WebSocket configuration ** @author: HEYUHUA * @date: 2021/1/7 11:54 */
@Configuration
public class WebSocketConfig {

    /** * Inject a ServerEndpointExporter, which automatically registers the WebSocket endpoint declared with the @ServerEndpoint annotation */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(a) {
        return newServerEndpointExporter(); }}Copy the code

Service interface class:

package com.hyh.websocket;

import javax.websocket.Session;

/** * WebSocket server interface ** @author: heyuhua * @date: 2021/1/7 11:51 */
public interface IWebSocketServer {

    Call ** @param session */
    void onOpen(Session session, String userId);

    /** * call ** @param message * @param session */
    void onMessage(String message, Session session);

    /** * connection close call */
    void onClose(a);

    Call ** @param session * @param error */ when an error or exception occurs
    void onError(Session session, Throwable error);
}






Copy the code

WebSocket support classes:

package com.hyh.websocket.support;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hyh.utils.common.StringUtils;
import com.hyh.websocket.IWebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

** @author: heyuhua * @date: 2021/1/7 14:07 */
public class WebSocketServerSupport implements IWebSocketServer {

    private static Logger LOG = LoggerFactory.getLogger(WebSocketServerSupport.class);
    /** * static variable used to record the number of current online connections. It should be designed to be thread-safe. * /
    private static int onlineCount = 0;
    /** * A thread-safe Set for the Concurrent package, used to hold each client's corresponding MyWebSocket object. * /
    private static ConcurrentHashMap<String, WebSocketServerSupport> webSocketMap = new ConcurrentHashMap<>();
    /** * Connects to a client through which to send data to the client */
    private Session session;
    /** * receive userId */
    private String userId;

    /** * Connection established successfully called method */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            webSocketMap.put(userId, this);
        } else {
            webSocketMap.put(userId, this);
            addOnlineCount();
        }
        LOG.info("User Connection :" + userId + ", current online population is :" + getOnlineCount());
        try {
            sendMessage("Connection successful");
        } catch (IOException e) {
            LOG.error("Users." + userId + ", network exception!!!!!!"); }}/** * the connection closes the called method */
    @OnClose
    public void onClose(a) {
        if (webSocketMap.containsKey(userId)) {
            webSocketMap.remove(userId);
            // Delete from set
            subOnlineCount();
        }
        LOG.info("User logout :" + userId + ", current online population is :" + getOnlineCount());
    }

    /** * @param message the message sent by the client */
    @OnMessage
    public void onMessage(String message, Session session) {
        LOG.info("User message :" + userId + ", a message:" + message);
        // You can send group messages
        // Save the message to the database, redis
        if (StringUtils.isNotBlank(message)) {
            try {
                // Parse the sent packet
                JSONObject jsonObject = JSON.parseObject(message);
                // Append the sender (to prevent string modification)
                jsonObject.put("fromUserId".this.userId);
                String toUserId = jsonObject.getString("toUserId");
                // To the websocket corresponding to the toUserId user
                if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
                    webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
                } else {
                    LOG.error("Requested userId:" + toUserId + "Not on this server");
                    // Otherwise not on the server, send to mysql or redis}}catch(Exception e) { e.printStackTrace(); }}}/** * @param session @param error */
    @OnError
    public void onError(Session session, Throwable error) {
        LOG.error("User error :" + this.userId + ",原因:" + error.getMessage());
        error.printStackTrace();
    }

    /** * implement server active push */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /** * Send a custom message */
    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
        LOG.info("Send a message to :" + userId + ", message :" + message);
        if (StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
            webSocketMap.get(userId).sendMessage(message);
        } else {
            LOG.error("User" + userId + ", not online!); }}public static synchronized int getOnlineCount(a) {
        return onlineCount;
    }

    public static synchronized void addOnlineCount(a) {
        WebSocketServerSupport.onlineCount++;
    }

    public static synchronized void subOnlineCount(a) { WebSocketServerSupport.onlineCount--; }}Copy the code

3. Configuration file

The code is as follows (example) :

server:
  port: 8088


Copy the code

Unit testing

The test code is as follows (example) :


import com.hyh.websocket.support.WebSocketServerSupport;
import org.springframework.stereotype.Component;

import javax.websocket.server.ServerEndpoint;

** @author: heyuhua * @date: 2021/1/7 15:56 * /
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer extends WebSocketServerSupport {
 // Available browser test, WebSocketServer class in com.hyh.core.web of hyh-boot-ore
 / / open the websocket test online address, enter the address ws: / / localhost: 8088 / websocket / 1 can be tested
 // The implementation methods are all in the WebSocketServerSupport class, yes, the purpose is to allow you to integrate directly to use


}


Copy the code

conclusion

For more usage, please click below to view the source code. Does it feel very simple? Follow me as I reveal more advanced usage of Quartz

Source code: click here to view the source code.