Introduction and application of WebSocket principle

1. Related concepts and principles

Too lazy to write, here is the introduction: https://my.oschina.net/kdy1994/blog/809802

2. WebSocket life cycle

  • Open: @OnOpen ; void method, optional with parameters a Session, an EndPointConfig, any number of @PathParam
  • Message: @OnMessage ; method parameters a Session, an EndPointConfig, any number of @PathParam, message, fragmentation flag bit (Boolean, true-last; false-not)
                message type
                        * text message : String, Reader
                        * binary : ByteBuffer, byte[], InputStream
                        pong message : PongMessage interface instance
                Return type
                        void:
                        non-void: The return value will be sent to the sender of the message.
  • Error: @OnError : Throwable, Session, multiple @PathParam with error message
  • Close: @ OnClose : Can bring close information CloseReason, Session, multiple @PathParam

3. Application and implementation of WebSocket

In the latest project, because it is necessary to control that users can only log in in one place, and display the login information in time, it is implemented with WebSocket.

Server implementation

   @EnableWebSocket declares that the class supports WebSocket

/**
 * The @ServerEndpoint annotation is a class-level annotation, its function is to define the current class as a websocket server,
 * The value of the annotation will be used to access the URL address of the terminal that listens for user connections, and the client can connect to the WebSocket server through this URL
 */
@ServerEndpoint("/websocket/{tstr}")
public class WebSocketForJSP {
    //The thread-safe Set of the concurrent package is used to store the MyWebSocket object corresponding to each client. If you want to realize the communication between the server and a single client, you can use Map to store, where Key can be the user ID
    public static CopyOnWriteArraySet<WebSocketForJSP> webSocketSet = new CopyOnWriteArraySet<WebSocketForJSP>();

    //A connection session with a client, which needs to be used to send data to the client
    private Session session;
    // Login Username
    public String userName;
    // Affiliation IP
    public String ip;
    
    
   
    /**
     * The method to be called successfully when the connection is established
     * @param session optional parameters. session is a connection session with a client, which needs to be used to send data to the client
     */
    @OnOpen
    public void onOpen(@PathParam("tstr") String tstr, Session session){
       String[] str = tstr.split(",");
       
       this.userName = str[0];
       this.ip = str[1];
        this.session = session;
        
        Boolean isIn = false;
        for (WebSocketForJSP socket : WebSocketForJSP.webSocketSet) {
           if(userName.equals(socket.userName) && ip.equals(socket.ip)){
              isIn = true;
              System.out.println("websocket is connected: "+userName+" "+ip);
              //delete old, add new
              webSocketSet.remove(socket);
              webSocketSet.add(this);
              break;
           }
        }  
        if(! isIn){
           webSocketSet.add(this); //Add to set
           System.out.println("A new connection is added! The current online number is" + getOnlineCount());
        }
    }

    /**
     * Method to be called when the connection is closed
     */
    @OnClose
    public void onClose(){
        webSocketSet.remove(this); //Remove from set
        System.out.println("A connection is closed! The current online number is" + getOnlineCount());
    }

    /**
     * Method called after receiving client message
     * @param message The message sent by the client
     * @param session optional parameters
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Message from client: " + message);
        /*
        try {
         this.sendMessage("Server reply message:"+this.userName);
      } catch (IOException e) {
         e.printStackTrace ();
      }
      */
    }
    
    /**
     * Called when an error occurs
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("Error occurred");
        this.onClose();
        error.printStackTrace();
    }

    /**
     * This method is different from the above methods. No annotations are used, it is a method to be added according to your own needs.
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException{
       System.out.println("Return result ----------------->:"+message);
        this.session.getAsyncRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }

    public static synchronized int getOnlineCount() {
        return WebSocketForJSP.webSocketSet.size();
    }
    
}

//Then you can judge where the user is logged in

// Determine if logged in
      for(WebSocketForJSP item: WebSocketForJSP.webSocketSet){
       if(item.userName.equals(userName)){
          return "User is logged in on another computer!";
       }
       String userIp  = IpUtils.getIpAddr(request);
       if(item.ip.equals(userIp)){
          return "Only one user is allowed to log in to the same IP";
       }
      }

Client call

/**
 * Push user java to get user information
 */
function sendWebSocketMsg(){
    //Determine whether the current browser supports WebSocket
// var test = window.location.host;
// var IP = test.split(":");
   var tstr = userName +","+localIP
    if ('WebSocket' in window) {
       //The parameters here only allow strings, not json
       websocket = new WebSocket(getRootPath().replace("http","ws")+"/websocket/"+tstr);
    }
    //Callback method for connection error
    websocket.onerror = function () {
       websocket.close();
    };

    //Callback method for successful connection establishment
    websocket.onopen = function () {
       //setInterval(function(){
           websocket.send (tstr);
       //}, 10 * 1000);
    }
   //Listen to the window closing event, when the window is closed, take the initiative to close the websocket connection to prevent the window from being closed before the connection is disconnected, and the server side will throw an exception.
   window.onbeforeunload = function () {
      websocket.close();
   }
    //Callback method for received message
    websocket.onmessage = function (event) {
       try {
          var result = JSON.parse(event.data);
           // is it an object
           if(typeof(result) == "object" && Object.prototype.toString.call(result).toLowerCase() == "[object object]" && !result.length){
              if(result.msgType != null && typeof(result.msgType) != "undefined"){
                 // load-automatic operation and maintenance
                 debugger;
                 window.showScriptDiagle(result);
              }else{
                 debugger;
                 // echo health-operation and maintenance experience
                 $(window.frames[0])[0].doScriptFn(result);
              }
           }
      } catch (e) {
         if("logOut" == event.data){
            websocket.close();
            sessionStorage.setItem("oneUser",true);
             location.href = getRootPath()+"/jsps/login/login.jsp";
         }else if("logOutByIp" == event.data){
            websocket.close();
            sessionStorage.setItem("oneIp",true);
             location.href = getRootPath()+"/jsps/login/login.jsp";
         }
      }
       console.log(event.data);
    }

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325165096&siteId=291194637
Recommended