Write in front
This exception is not another exception. The exception mentioned in the title is a business exception.
Recently, I made a demand for fire equipment inspection. If any abnormality is found in the inspection, submit it through the mobile terminal, and obtain the information and location of the equipment in real time on the background real-time monitoring page, and then arrange employees to deal with it.
Because the server needs to actively send messages to the client, it is easy to think of using WebSocket to realize this function.
Websocket will not be introduced. The link is as follows: https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
The front end is slightly complex. You need to use the mouse to trace points on a position distribution map, locate various devices and render according to different screen sizes. This paper will not introduce it, but simply use page style to render the effect.
Green represents normal and red represents abnormal
The expected effect is that before receiving the request, the exception is submitted by - > the king with id 3, and the king with id 3 turns red
realization:
front end:
Direct paste code
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Real time monitoring</title> 6 </head> 7 <style> 8 .item { 9 display: flex; 10 border-bottom: 1px solid #000000; 11 justify-content: space-between; 12 width: 30%; 13 line-height: 50px; 14 height: 50px; 15 } 16 17 .item span:nth-child(2){ 18 margin-right: 10px; 19 margin-top: 15px; 20 width: 20px; 21 height: 20px; 22 border-radius: 50%; 23 background: #55ff00; 24 } 25 .nowI{ 26 background: #ff0000 !important; 27 } 28 </style> 29 <body> 30 <div id="app"> 31 <div v-for="item in list" class="item"> 32 <span>{{item.id}}.{{item.name}}</span> 33 <span :class='item.state==-1?"nowI":""'></span> 34 </div> 35 </div> 36 </body> 37 <script src="./js/vue.min.js"></script> 38 <script type="text/javascript"> 39 var vm = new Vue({ 40 el: "#app", 41 data: { 42 list: [{ 43 id: 1, 44 name: 'Zhang San', 45 state: 1 46 }, 47 { 48 id: 2, 49 name: 'Li Si', 50 state: 1 51 }, 52 { 53 id: 3, 54 name: 'Wang Wu', 55 state: 1 56 }, 57 { 58 id: 4, 59 name: 'Mei Mei Han', 60 state: 1 61 }, 62 { 63 id: 5, 64 name: 'Li Lei', 65 state: 1 66 }, 67 ] 68 } 69 }) 70 71 var webSocket = null; 72 if ('WebSocket' in window) { 73 //Create WebSocket object 74 webSocket = new WebSocket("ws://localhost:18801/webSocket/" + getUUID()); 75 76 //Connection succeeded 77 webSocket.onopen = function() { 78 console.log("Connected"); 79 webSocket.send("Message sending test") 80 } 81 //Message received 82 webSocket.onmessage = function(msg) { 83 //Processing messages 84 var serverMsg = msg.data; 85 var t_id = parseInt(serverMsg) //The ID and string of the message sent from the server must be converted into int type for comparison 86 for (var i = 0; i < vm.list.length; i++) { 87 var item = vm.list[i]; 88 if(item.id == t_id){ 89 item.state = -1; 90 vm.list.splice(i,1,item) 91 break; 92 } 93 } 94 }; 95 96 //Close event 97 webSocket.onclose = function() { 98 console.log("websocket Closed"); 99 }; 100 //An error event occurred 101 webSocket.onerror = function() { 102 console.log("websocket An error has occurred"); 103 } 104 } else { 105 alert("Unfortunately, your browser does not support WebSocket!") 106 } 107 108 function getUUID() { //Get unique UUID 109 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 110 111 var r = Math.random() * 16 | 0, 112 v = c == 'x' ? r : (r & 0x3 | 0x8); 113 return v.toString(16); 114 }); 115 } 116 </script> 117 </html>
Back end:
The project structure is like this. There are key comments in the following code, so the description will not be repeated
1. Create a new SpringBoot project and select web and WebSocket dependencies
2. Configure application yml
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Real time monitoring</title> 6 </head> 7 <style> 8 .item { 9 display: flex; 10 border-bottom: 1px solid #000000; 11 justify-content: space-between; 12 width: 30%; 13 line-height: 50px; 14 height: 50px; 15 } 16 17 .item span:nth-child(2){ 18 margin-right: 10px; 19 margin-top: 15px; 20 width: 20px; 21 height: 20px; 22 border-radius: 50%; 23 background: #55ff00; 24 } 25 .nowI{ 26 background: #ff0000 !important; 27 } 28 </style> 29 <body> 30 <div id="app"> 31 <div v-for="item in list" class="item"> 32 <span>{{item.id}}.{{item.name}}</span> 33 <span :class='item.state==-1?"nowI":""'></span> 34 </div> 35 </div> 36 </body> 37 <script src="./js/vue.min.js"></script> 38 <script type="text/javascript"> 39 var vm = new Vue({ 40 el: "#app", 41 data: { 42 list: [{ 43 id: 1, 44 name: 'Zhang San', 45 state: 1 46 }, 47 { 48 id: 2, 49 name: 'Li Si', 50 state: 1 51 }, 52 { 53 id: 3, 54 name: 'Wang Wu', 55 state: 1 56 }, 57 { 58 id: 4, 59 name: 'Mei Mei Han', 60 state: 1 61 }, 62 { 63 id: 5, 64 name: 'Li Lei', 65 state: 1 66 }, 67 ] 68 } 69 }) 70 71 var webSocket = null; 72 if ('WebSocket' in window) { 73 //Create WebSocket object 74 webSocket = new WebSocket("ws://localhost:18801/webSocket/" + getUUID()); 75 76 //Connection succeeded 77 webSocket.onopen = function() { 78 console.log("Connected"); 79 webSocket.send("Message sending test") 80 } 81 //Message received 82 webSocket.onmessage = function(msg) { 83 //Processing messages 84 var serverMsg = msg.data; 85 var t_id = parseInt(serverMsg) //The ID and string of the message sent from the server must be converted into int type for comparison 86 for (var i = 0; i < vm.list.length; i++) { 87 var item = vm.list[i]; 88 if(item.id == t_id){ 89 item.state = -1; 90 vm.list.splice(i,1,item) 91 break; 92 } 93 } 94 }; 95 96 //Close event 97 webSocket.onclose = function() { 98 console.log("websocket Closed"); 99 }; 100 //An error event occurred 101 webSocket.onerror = function() { 102 console.log("websocket An error has occurred"); 103 } 104 } else { 105 alert("Unfortunately, your browser does not support WebSocket!") 106 } 107 108 function getUUID() { //Get unique UUID 109 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 110 111 var r = Math.random() * 16 | 0, 112 v = c == 'x' ? r : (r & 0x3 | 0x8); 113 return v.toString(16); 114 }); 115 } 116 </script> 117 </html>
3. WebSocketConfig configuration class
1 @Configuration 2 public class WebSocketConfig { 3 4 /** 5 * Inject a ServerEndpointExporter, and the Bean will automatically register the websocket endpoint declared with the @ ServerEndpoint annotation 6 */ 7 @Bean 8 public ServerEndpointExporter serverEndpointExporter(){ 9 return new ServerEndpointExporter(); 10 } 11 }
4. WebSocketServer class is used to interact between server and client
1 /** 2 * @author jae 3 * @ServerEndpoint("/webSocket/{uid}") The front end links to the back end through this URI 4 */ 5 6 @ServerEndpoint("/webSocket/{uid}") 7 @Component 8 public class WebSocketServer { 9 10 private static Logger log = LoggerFactory.getLogger(WebSocketServer.class); 11 12 //Static variable, used to record the current number of online connections. It should be designed to be thread safe. 13 private static final AtomicInteger onlineNum = new AtomicInteger(0); 14 15 //The thread safe Set of the concurrent package is used to store the WebSocketServer object corresponding to each client. 16 private static CopyOnWriteArraySet<Session> sessionPools = new CopyOnWriteArraySet<Session>(); 17 18 /** 19 * There are clients connected successfully 20 */ 21 @OnOpen 22 public void onOpen(Session session, @PathParam(value = "uid") String uid){ 23 sessionPools.add(session); 24 onlineNum.incrementAndGet(); 25 log.info(uid + "join webSocket!The current number is" + onlineNum); 26 } 27 28 /** 29 * Method called for connection closure 30 */ 31 @OnClose 32 public void onClose(Session session) { 33 sessionPools.remove(session); 34 int cnt = onlineNum.decrementAndGet(); 35 log.info("There are connections closed. The current number of connections is:{}", cnt); 36 } 37 38 /** 39 * send message 40 */ 41 public void sendMessage(Session session, String message) throws IOException { 42 if(session != null){ 43 synchronized (session) { 44 session.getBasicRemote().sendText(message); 45 } 46 } 47 } 48 49 /** 50 * Mass messaging 51 */ 52 public void broadCastInfo(String message) throws IOException { 53 for (Session session : sessionPools) { 54 if(session.isOpen()){ 55 sendMessage(session, message); 56 } 57 } 58 } 59 60 /** 61 * An error occurred 62 */ 63 @OnError 64 public void onError(Session session, Throwable throwable){ 65 log.error("An error occurred"); 66 throwable.printStackTrace(); 67 } 68 69 }
5. WebSocketController class, used for interface testing
1 @RestController 2 @RequestMapping("/open/socket") 3 public class WebSocketController { 4 5 @Value("${mySocket.myPwd}") 6 public String myPwd; 7 8 @Autowired 9 private WebSocketServer webSocketServer; 10 11 /** 12 * Mobile client request interface 13 * @param id Device ID with exception 14 * @param pwd Password (remember to encrypt in actual development) 15 * @throws IOException 16 */ 17 @PostMapping(value = "/onReceive") 18 public void onReceive(String id,String pwd) throws IOException { 19 if(pwd.equals(myPwd)){ //If the password verification is consistent (for example, there is also a verification of password encryption in the actual development), mass sending will be carried out 20 webSocketServer.broadCastInfo(id); 21 } 22 } 23 24 }
test
1. Open the front page to connect to WebSocket
Console output, connection successful
2. Because it is analog data, all display is normal, and there is no exception. The page is rendered when submitting
3. Next, we submit an exception using the interface testing tool Postman
Note the state change of the data with id 3
We can see that the status of Wang Wu with id 3 has become abnormal, and the real-time communication is successful.
reference resources: https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
last
There is a demand for real-time monitoring in this aspect. You can refer to it.
Shortcomings are welcome to point out. If you find it useful, just point out a recommendation!