In a project development , Using the Netty Network application framework , as well as MQTT Send and receive message data , This requires the background to actively push the obtained messages to the front end , So it was used MQTT, It is hereby recorded that .
WebSocket The protocol is based on TCP A new network protocol . It realizes full duplex communication between client and server , I've learned computer network , Since it's full duplex , It means that the server can actively send information to the client . This is in line with our push technology or the function of multi person online chat .
blockbuster !Spring Boot 2.5.0 Hot release , Can you still learn to move ?
Why not use HTTP What about the agreement? ? This is because HTTP It's simplex communication , Communication can only be initiated by the client , The client asks for , The server handles , This is too much trouble . therefore websocket emerge as the times require .
Dry goods : In depth analysis of MySQL Index and SQL Tuning practice
Let's start using Springboot Start integrating . The following cases are all tested successfully on my own computer , You can modify it according to your own functions . My project structure is as follows :
What is a data Lake ? Why data lake ? How to build a lake ? how ETL?
Maven rely on :
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
Enable WebSocket The support is also very simple , A few lines of code :
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * @ Auther: Ma Chaowei * @ Date: 2020/06/16/14:35 * @ Description: Turn on WebSocket Support */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
because WebSocket It is similar to the form of client server ( use ws agreement ), So here WebSocketServer In fact, it's equivalent to a ws Agreed Controller
Here is the specific business code :
package cc.mrbird.febs.external.webScoket; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; import java.util.concurrent.CopyOnWriteArraySet; /** * Created with IntelliJ IDEA. * @ Auther: Ma Chaowei * @ Date: 2020/06/16/14:35 * @ Description: * @ ServerEndpoint An annotation is a class level annotation , Its main function is to define the current class as a websocket Server side , * The value of the annotation will be used to monitor the terminal access of the user connection URL Address , The client can use this URL To connect to WebSocket Server side */ @Component @Slf4j @Service @ServerEndpoint("/api/websocket/{sid}") public class WebSocketServer { // Static variables , To record the current number of online connections . It should be designed to be thread safe . private static int onlineCount = 0; //concurrent Thread safety of package Set, Used to store the corresponding MyWebSocket object . private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>(); // A connection session with a client , It is needed to send data to the client private Session session; // receive sid private String sid = ""; /** * Connection establishment method called successfully */ @OnOpen public void onOpen(Session session, @PathParam("sid") String sid) { this.session = session; webSocketSet.add(this); // Join in set in this.sid = sid; addOnlineCount(); // The online number 1 try { sendMessage("conn_success"); log.info(" There's a new window to start listening :" + sid + ", The current online population is :" + getOnlineCount()); } catch (IOException e) { log.error("websocket IO Exception"); } } /** * Connection closes the called method */ @OnClose public void onClose() { webSocketSet.remove(this); // from set Delete in subOnlineCount(); // The online number minus 1 // When disconnected , Update motherboard occupancy to release log.info(" Released sid by :"+sid); // Here you are When released , Business to deal with log.info(" There is a connection closed ! The current online population is " + getOnlineCount()); } /** * Method called upon receipt of a client message * @ Param message The message sent by the client */ @OnMessage public void onMessage(String message, Session session) { log.info(" Received from window " + sid + " Information about :" + message); // Group-sent message for (WebSocketServer item : webSocketSet) { try { item.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } /** * @ Param session * @ Param error */ @OnError public void onError(Session session, Throwable error) { log.error(" An error occurred "); error.printStackTrace(); } /** * Realize server active push */ public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * Group custom messages */ public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException { log.info(" Push message to window " + sid + ", Push content :" + message); for (WebSocketServer item : webSocketSet) { try { // You can only push this one here sid Of , by null Then all push if (sid == null) { // item.sendMessage(message); } else if (item.sid.equals(sid)) { item.sendMessage(message); } } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; } public static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() { return webSocketSet; } }
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * Created with IntelliJ IDEA. * * @ Auther: Ma Chaowei * @ Date: 2020/06/16/14:38 * @ Description: */ @Controller("web_Scoket_system") @RequestMapping("/api/socket") public class SystemController { // Page request @GetMapping("/index/{userId}") public ModelAndView socket(@PathVariable String userId) { ModelAndView mav = new ModelAndView("/socket1"); mav.addObject("userId", userId); return mav; } // Push data interface @ResponseBody @RequestMapping("/socket/push/{cid}") public Map pushToWeb(@PathVariable String cid, String message) { Map<String,Object> result = new HashMap<>(); try { WebSocketServer.sendInfo(message, cid); result.put("code", cid); result.put("msg", message); } catch (IOException e) { e.printStackTrace(); } return result; } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Java Back end WebSocket Of Tomcat Realization </title> <script type="text/javascript" src="js/jquery.min.js"></script> </head> <body> <div id="main" style="width: 1200px;height:800px;"></div> Welcome<br/><input id="text" type="text" /> <button onclick="send()"> Send a message </button> <hr/> <button onclick="closeWebSocket()"> close WebSocket Connect </button> <hr/> <div id="message"></div> </body> <script type="text/javascript"> var websocket = null; // Determine whether the current browser supports it WebSocket if('WebSocket' in window) { // Change your address to websocket = new WebSocket("ws://192.168.100.196:8082/api/websocket/100"); } else { alert(' Current browser Not support websocket') } // Callback method for connection error websocket.onerror = function() { setMessageInnerHTML("WebSocket Connection error "); }; // Callback method for successful connection establishment websocket.onopen = function() { setMessageInnerHTML("WebSocket Successful connection "); } var U01data, Uidata, Usdata // The callback method that receives the message websocket.onmessage = function(event) { console.log(event); setMessageInnerHTML(event); setechart() } // Call-back method for connection closure websocket.onclose = function() { setMessageInnerHTML("WebSocket Connection is closed "); } // Listen for window closing events , When the window closes , Active close websocket Connect , Prevent Windows from closing before the connection has been disconnected ,server The end throws an exception . window.onbeforeunload = function() { closeWebSocket(); } // Displays the message on the web page function setMessageInnerHTML(innerHTML) { document.getElementById('message').innerHTML += innerHTML + '<br/>'; } // close WebSocket Connect function closeWebSocket() { websocket.close(); } // Send a message function send() { var message = document.getElementById('text').value; websocket.send('{"msg":"' + message + '"}'); setMessageInnerHTML(message + " "); } </script> </html>
backstage : If there is a connection request
The front desk shows :
Regular expressions are commonly used ( Quick reference manual )
I have a problem in the middle , That is to say WebSocket Start up prior to spring Containers , Which leads to WebSocketServer Call business in Service Null pointer exception will be reported
So you need to be in WebSocketServer Will be used in the service Give static initialization : As shown in the figure :
Spring Security 5.5 Release , Formal dress OAuth2.0 The fifth mode of Authorization
You also need to do the following configuration :
This article is from WeChat official account. - Program the ape DD(didispace)
The source and reprint of the original text are detailed in the text , If there is any infringement , Please contact the [email protected] Delete .
Original publication time : 2021-05-23
Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .