Spring boot project integrates websocket to realize connectivity

Posted by aahh on Wed, 12 Feb 2020 16:30:55 +0100

Spring boot project integrates websocket to realize connectivity

brief introduction

First of all, this summary is relatively simple. The first time I contacted websocket, it was all online Baidu. After a trial, I succeeded in a muddle headed way. There are still some doubts and puzzles in some places. However, record them first, and the follow-up study will be improved one by one

pom.xml introduces dependency

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

Create websocket configuration file for spring boot project

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

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

//    @Bean
//There's a little doubt here. It's a temporary comment. It doesn't affect the use
//    public WebSocketEndpointConfigure newConfigure() {
//        return new WebSocketEndpointConfigure();
//    }

}

websocketServer core code

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

//Comment of component causes server to inject into spring container
@Component
//@ServerEndpoint(value = "/webSocket/{userId}", configurator = WebSocketEndpointConfigure.class)
//This is originally the above comment, but the class of WebSocketEndpointConfigure is introduced to report an error. Therefore, the temporary comment does not affect the use, the same as the above configuration class
//It's annotated as a whole
//The value in the serverEndpoint annotation represents the interface path and adopts restful style
@ServerEndpoint(value = "/webSocket/{userId}")
public class WebSocketServer {
    //ConcurrentHashMap is used to store the corresponding WebSocketServer object of each client
    private static ConcurrentHashMap<String, Session> webSocketSet = new ConcurrentHashMap<>();
    private Logger logger =LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * Method successfully called for connection establishment
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        //Here, userId is used as a key to store the identity of the client and the background channel, and stored in concurrenthashmap < string, session >
        webSocketSet.put(userId, session);//Establish channel cache information
        //For related business processing, judge the role according to the user ID obtained, query whether there is a message to push to the role according to the role ID, and push if there is one
        System.out.println("******************Write the logic code after creating the channel*************************************************");
        System.out.println("user id by" + userId+"establish websocket Success");
        System.out.println("******************Write the logic code after creating the channel above*************************************************");
//        List<String> totalPushMsgs = new ArrayList<String>();
//        Totalpushmsg.add ("user id is" + userId + "websocket is established successfully");
//        if (totalPushMsgs != null && !totalPushMsgs.isEmpty()) {
//            totalPushMsgs.forEach(e -> sendMessage(userId, e));
//        }
    }

    /**
     * send message
     */
    public void sendMessage(String userId,String message){
        try {
            Session currentSession=webSocketSet.get(userId);
            if (currentSession!=null){
                currentSession.getBasicRemote().sendText(message);
            }
            logger.info("Push message succeeded, message is:"+message);
        }catch (IOException e){

        }
    }

    /**
     * Custom message
     */
    public static void sendInfo(String userId,String message) throws IOException {
        Session currentSession=webSocketSet.get(userId);
        if (currentSession!=null){
            currentSession.getBasicRemote().sendText(message);
        }
    }

    /**
     * When the user exits, the link closes the called method
     */
    public static void onCloseConection(String userId){
        webSocketSet.remove(userId);
    }

    /**
     * Method called by link close
     */
    @OnClose
    public void onClose(){
        System.out.println("websocsdfsket Shut down successfully");
        logger.info("A client closes the link");
    }

    /**
     * Called when an error occurs
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("webSocket Error occurred");
    }

    /**
     * Method of calling after receiving client message
     */
//    public void onMessage(String message,Session session){
//
//    }

}

An entity class not understood, annotated to be solved

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.websocket.server.ServerEndpointConfig;

public class WebSocketEndpointConfigure extends ServerEndpointConfig.Configurator implements ApplicationContextAware {

    private static volatile BeanFactory context;

    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
        return context.getBean(clazz);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

    }
}

js of front-end page, creating websocket for operation monitoring

	var websocket = null;

    //Determine whether the current browser supports WebSocket
    if ('WebSocket' in window) {
        console.log("Try to create socket passageway")
        websocket = new WebSocket("ws://localhost:8080 / project name / webSocket/111“);
    }
    else {
        alert('Not support websocket')
    }

    //Callback method with connection error
    websocket.onerror = function () {
        setMessageInnerHTML("error");
    };

    //Callback method for successful connection establishment
    websocket.onopen = function (event) {
        setMessageInnerHTML("open");
    }

    //Callback method of received message
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data);
    }

    //Callback method for connection closing
    websocket.onclose = function () {
        setMessageInnerHTML("close");
    }

    //Monitor the window closing event. When the window is closed, take the initiative to close the websocket connection to prevent closing the window before the connection is disconnected. The server will throw an exception.
    window.onbeforeunload = function () {
    	console.log("Close web window close channel")
        websocket.close();
    }

    //Show messages on Web pages
    function setMessageInnerHTML(innerHTML) {
        console.log("The method called is"+innerHTML);
    }

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

    //send message
    function send() {
        websocket.send("asdfs");
    }

It is worth noting that the intercepted release

Because I am a fast development tool, the interceptor of the system itself will intercept the link of the front end to create websocket,

  filterChainDefinitionMap.put("/webSocket/**", "anon");
Published 20 original articles, won praise 7, visited 10000+
Private letter follow

Topics: Session Spring xml socket