The use of websocket in spring boot + Vue

Keywords: Java Session socket SpringBoot

1. An Implementation of websocket in springboot

In the java background, websocket is configured as a server-side configuration, which is as follows

@Configuration
public class WebSocketConfig {
  
    @Bean(name="serverEndpointExporter")
    public ServerEndpointExporter getServerEndpointExporterBean(){
        return new ServerEndpointExporter();
    }
}

After adding the above configuration, you can edit your own websocket implementation class as follows

  

@Component
@ServerEndpoint(value = "/messageSocket/{userId}")
public class MessageWebSocket {

    private static final Logger logger = LoggerFactory.getLogger(MessageWebSocket.class);

    /**
     * Static variables that record the number of current online connections. It should be designed to be thread-safe.
     */
    private static int onlineCount = 0;

    /**
     * key: userId value: sessionIds
     */
    private static ConcurrentHashMap<Integer, ConcurrentLinkedQueue<String>> userSessionMap =  new ConcurrentHashMap<>();

    /**
     * concurrent The thread-safe Map of the package is used to store MyWebSocket objects corresponding to each client.
     */
    private static ConcurrentHashMap<String, MessageWebSocket> websocketMap = new ConcurrentHashMap<>();

    /**
     * key: sessionId value: userId
     */
    private static ConcurrentHashMap<String, Integer> sessionUserMap = new ConcurrentHashMap<>();

    /**
     * The current connection session needs to be used to send data to the client
     */
    private Session session;

    /**
     * Connection Establishment Successful Call Method
     * */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId) {
        System.out.println(applicationContext);
        try {
            this.session = session;
            String sessionId = session.getId();
            //establish userId and sessionId Relationship
            if(userSessionMap.containsKey(userId)) {
                userSessionMap.get(userId).add(sessionId);
            }else{
                ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
                queue.add(sessionId);
                userSessionMap.put(userId, queue);
            }
            sessionUserMap.put(sessionId, userId);
            //establish sessionId and websocket Reference Relations
            if(!websocketMap.containsKey(sessionId)){
                websocketMap.put(sessionId, this);
                addOnlineCount();           //On-line number plus 1
            }
        }catch (Exception e){
            logger.error("connection failed");
            String es = ExceptionUtils.getFullStackTrace(e);
            logger.error(es);
        }
    }

    /**
     * Connection Close Call Method
     */
    @OnClose
    public void onClose() {
        String sessionId = this.session.getId();
        //remove userId and sessionId Relationship
        Integer userId = sessionUserMap.get(sessionId);
        sessionUserMap.remove(sessionId);
        if(userId != null) {
            ConcurrentLinkedQueue<String> sessionIds = userSessionMap.get(userId);
            if(sessionIds != null) {
                sessionIds.remove(sessionId);
                if (sessionIds.size() == 0) {
                    userSessionMap.remove(userId);
                }
            }
        }
        //remove sessionId and websocket Relationship
        if (websocketMap.containsKey(sessionId)) {
            websocketMap.remove(sessionId);
            subOnlineCount();           //On-line number minus 1
        }
    }

    /**
     * Method called after receiving client message
     *
     * @param messageStr Message sent by client
     **/
    @OnMessage
    public void onMessage(String messageStr, Session session, @PathParam("userId") Integer userId) throws IOException {
   
    }

    /**
     *
     * @param session
     * @param error Callback when a connection error occurs
     */
    @OnError
    public void onError(Session session, Throwable error) {
        String es = ExceptionUtils.getFullStackTrace(error);
        logger.error(es);
    }


    /**
     * Implementing Server Active Push
     */
    public void sendMessage(String message, Integer toUserId) throws IOException {
        if(toUserId != null && !StringUtil.isEmpty(message.trim())){
            ConcurrentLinkedQueue<String> sessionIds = userSessionMap.get(toUserId);
            if(sessionIds != null) {
                for (String sessionId : sessionIds) {
                    MessageWebSocket socket = websocketMap.get(sessionId);
                    socket.session.getBasicRemote().sendText(message);
                }
            }
        }else{
            logger.error("Receiving user connection not found, not connected or disconnected");
        }
    }

    public void sendMessage(String message, Session session) throws IOException {
        session.getBasicRemote().sendText(message);
    }

     /**
    *Get online numbers
    */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
     /**
    *Online population plus one
    */
    public static synchronized void addOnlineCount() {
        MessageWebSocket.onlineCount++;
    }
    /**
    *Reduce the number of people online by one
    */
    public static synchronized void subOnlineCount() {
        MessageWebSocket.onlineCount--;
    }
}

Since then, the work of the back-end server has been done, how to connect the front-end as a client, please continue to look down.

To achieve automatic disconnection reconnection, we use reconnecting-websocket.js component

//websocket Connection instance
let websocket = null;

//Initial remarks websocket Example
function initWebSocket(userId, onMessageFunc) {
    // ws address -->Here is your request path
    let host = urlConfig.wsUrl +  'messageSocket/' + userId;
    if ('WebSocket' in window) {
        websocket = new ReconnectingWebSocket(host);
        // Connection error
        websocket.onerror = function () {
        }

        // Successful connection
        websocket.onopen = function () {
        }

        // Receiving a call back from the message, e.data For information received
        websocket.onmessage = function (e) {
        }

        // Callback for connection closure
        websocket.onclose = function () {
        }
        
        //Listen for window closure events and actively close when the window closes websocket Connect to prevent the window from closing before the connection is disconnected. server The end throws an exception.
        window.onbeforeunload = function () {
            closeWebSocket();
        }
    } else {
        alert('Current browsers do not support websocket')
        return;
    }
}

//Close WebSocket Connect
function closeWebSocket() {
    websocket.close();
}

//send message
function sendMessage(message){
   websocket.send(message);
}

So far, a simple and complete websocket has been completed, and the specific functions can be extended as a basic basis.

Posted by The Wise One on Mon, 30 Sep 2019 16:40:52 -0700