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(); } }