告別掉線(xiàn)!SpringBoot+WebSocket打造超穩(wěn)定實(shí)時(shí)監(jiān)控!
在現(xiàn)代化的系統(tǒng)架構(gòu)中,實(shí)時(shí)監(jiān)控?zé)o疑是提升效率和確保業(yè)務(wù)順暢運(yùn)行的關(guān)鍵之一。尤其是在設(shè)備巡檢等場(chǎng)景中,實(shí)時(shí)監(jiān)控系統(tǒng)可以確保及時(shí)發(fā)現(xiàn)問(wèn)題并快速響應(yīng)。本文將結(jié)合 SpringBoot + WebSocket 技術(shù),深入探討如何構(gòu)建一個(gè)超穩(wěn)定的實(shí)時(shí)監(jiān)控系統(tǒng),實(shí)時(shí)接收設(shè)備巡檢的異常信息,并在監(jiān)控界面上及時(shí)更新設(shè)備狀態(tài)。
我們將詳細(xì)講解如何通過(guò) WebSocket 實(shí)現(xiàn)服務(wù)器主動(dòng)向客戶(hù)端推送消息,確保監(jiān)控系統(tǒng)能夠?qū)崟r(shí)反映設(shè)備狀態(tài)的變化。通過(guò)一個(gè)簡(jiǎn)單的示例,我們將實(shí)現(xiàn)一個(gè)消防設(shè)備巡檢系統(tǒng),后臺(tái)服務(wù)可實(shí)時(shí)向前端頁(yè)面發(fā)送設(shè)備異常信息,并通過(guò) WebSocket 將這些信息推送到監(jiān)控頁(yè)面,實(shí)時(shí)更新設(shè)備狀態(tài)。
整體架構(gòu)
在本項(xiàng)目中,我們采用 Spring Boot 作為后端開(kāi)發(fā)框架,結(jié)合 WebSocket 實(shí)現(xiàn)實(shí)時(shí)消息推送。前端則使用 Vue 和 Element,并通過(guò) WebSocket 與后端建立實(shí)時(shí)通信連接。當(dāng)設(shè)備發(fā)生異常時(shí),前端會(huì)根據(jù) WebSocket 推送的數(shù)據(jù)動(dòng)態(tài)更新設(shè)備狀態(tài)。
項(xiàng)目結(jié)構(gòu)
- 前端: 基于 Vue 和 Element 實(shí)現(xiàn)的設(shè)備巡檢頁(yè)面,用戶(hù)可以通過(guò)頁(yè)面查看各設(shè)備的狀態(tài)并接收異常信息。
- 后端: 使用 Spring Boot 構(gòu)建 WebSocket 服務(wù)端,并通過(guò)
@ServerEndpoint注解創(chuàng)建 WebSocket 連接,實(shí)現(xiàn)與客戶(hù)端的實(shí)時(shí)消息推送。
實(shí)現(xiàn)步驟
配置 Spring Boot WebSocket 服務(wù)端
配置 application.yml 配置文件
# application.yml 配置
server:
port: 18801
mySocket:
myPwd: jae_123 # WebSocket 密碼校驗(yàn)WebSocket 配置類(lèi)
在 Spring Boot 項(xiàng)目中,我們需要?jiǎng)?chuàng)建一個(gè)配置類(lèi)來(lái)啟用 WebSocket。
package com.icoderoad.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 注入一個(gè) ServerEndpointExporter, 該 Bean 會(huì)自動(dòng)注冊(cè)使用 @ServerEndpoint 注解聲明的 WebSocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}WebSocket 服務(wù)端類(lèi)
WebSocket 服務(wù)端類(lèi)負(fù)責(zé)處理客戶(hù)端連接、消息發(fā)送和關(guān)閉連接等操作。
package com.icoderoad.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
@ServerEndpoint("/webSocket/{uid}")
@Component
public class WebSocketServer {
private static final AtomicInteger onlineNum = new AtomicInteger(0);
private static final CopyOnWriteArraySet<Session> sessionPools = new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session, @PathParam("uid") String uid) {
sessionPools.add(session);
onlineNum.incrementAndGet();
}
@OnClose
public void onClose(Session session) {
sessionPools.remove(session);
onlineNum.decrementAndGet();
}
public void sendMessage(Session session, String message) throws IOException {
if (session != null) {
session.getBasicRemote().sendText(message);
}
}
public void broadCastInfo(String message) throws IOException {
for (Session session : sessionPools) {
if (session.isOpen()) {
sendMessage(session, message);
}
}
}
@OnError
public void onError(Session session, Throwable throwable) {
throwable.printStackTrace();
}
}WebSocket Controller 處理前端請(qǐng)求
控制器類(lèi)負(fù)責(zé)接收來(lái)自客戶(hù)端的請(qǐng)求,并通過(guò) WebSocket 向所有連接的客戶(hù)端廣播消息。
package com.icoderoad.websocket;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@RequestMapping("/open/socket")
public class WebSocketController {
@Value("${mySocket.myPwd}")
private String myPwd;
@Autowired
private WebSocketServer webSocketServer;
@PostMapping("/onReceive")
public void onReceive(String id, String pwd) throws IOException {
if (pwd.equals(myPwd)) {
webSocketServer.broadCastInfo(id); // 廣播異常設(shè)備ID
}
}
}前端實(shí)現(xiàn):Vue + WebSocket
前端頁(yè)面采用 Vue 和 WebSocket 進(jìn)行實(shí)時(shí)通信。
前端 HTML 和 Vue 代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>實(shí)時(shí)監(jiān)控</title>
</head>
<style>
.item {
display: flex;
border-bottom: 1px solid #000000;
justify-content: space-between;
width: 30%;
line-height: 50px;
height: 50px;
}
.item span:nth-child(2){
margin-right: 10px;
margin-top: 15px;
width: 20px;
height: 20px;
border-radius: 50%;
background: #55ff00;
}
.nowI {
background: #ff0000 !important;
}
</style>
<body>
<div id="app">
<div v-for="item in list" class="item">
<span>{{item.id}}.{{item.name}}</span>
<span :class="item.state == -1 ? 'nowI' : ''"></span>
</div>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
list: [
{id: 1, name: '張三', state: 1},
{id: 2, name: '李四', state: 1},
{id: 3, name: '王五', state: 1},
{id: 4, name: '韓梅梅', state: 1},
{id: 5, name: '李磊', state: 1},
]
}
});
var webSocket = new WebSocket("ws://localhost:18801/webSocket/" + getUUID());
webSocket.onopen = function () {
console.log("已連接");
};
webSocket.onmessage = function (msg) {
var serverMsg = msg.data;
var t_id = parseInt(serverMsg); // 服務(wù)端發(fā)過(guò)來(lái)的消息,ID,string需轉(zhuǎn)化為int類(lèi)型才能比較
for (var i = 0; i < vm.list.length; i++) {
var item = vm.list[i];
if (item.id == t_id) {
item.state = -1;
vm.list.splice(i, 1, item);
break;
}
}
};
webSocket.onclose = function () {
console.log("websocket已關(guān)閉");
};
webSocket.onerror = function () {
console.log("websocket發(fā)生了錯(cuò)誤");
};
function getUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
</script>
</html>測(cè)試與結(jié)果
- 打開(kāi)前端頁(yè)面: 在瀏覽器中打開(kāi)監(jiān)控頁(yè)面,WebSocket 會(huì)自動(dòng)連接服務(wù)器并輸出連接成功的日志。
- 提交異常數(shù)據(jù): 使用 Postman 等接口測(cè)試工具向后端發(fā)送設(shè)備異常數(shù)據(jù),設(shè)備 ID 為 3 的設(shè)備狀態(tài)會(huì)變?yōu)榧t色(表示異常)。
結(jié)論
通過(guò) Spring Boot 和 WebSocket 的結(jié)合,成功實(shí)現(xiàn)了一個(gè)實(shí)時(shí)監(jiān)控系統(tǒng)。在這個(gè)系統(tǒng)中,服務(wù)端能夠主動(dòng)向客戶(hù)端推送消息,確保監(jiān)控?cái)?shù)據(jù)實(shí)時(shí)更新。利用 WebSocket 技術(shù),我們可以實(shí)現(xiàn)高效、穩(wěn)定、低延遲的實(shí)時(shí)通信,使得設(shè)備異常能夠快速傳遞到監(jiān)控平臺(tái),提高工作效率和安全性。這種基于 WebSocket 的實(shí)時(shí)監(jiān)控方案,不僅適用于設(shè)備巡檢場(chǎng)景,還可以擴(kuò)展應(yīng)用到其他需要實(shí)時(shí)反饋的系統(tǒng)中。
通過(guò)本文的實(shí)踐,我們可以看到 WebSocket 在實(shí)時(shí)通訊中的強(qiáng)大能力,使用 Spring Boot 構(gòu)建的 WebSocket 服務(wù)端具備了良好的擴(kuò)展性和穩(wěn)定性,非常適合處理這種實(shí)時(shí)性要求較高的業(yè)務(wù)場(chǎng)景。





























