在现代化的系统架构中,实时监控无疑是提升效率和确保业务顺畅运行的关键之一。尤其是在设备巡检等场景中,实时监控系统可以确保及时发现问题并快速响应。本文将结合 SpringBoot + WebSocket 技术,深入探讨如何构建一个超稳定的实时监控系统,实时接收设备巡检的异常信息,并在监控界面上及时更新设备状态。
我们将详细讲解如何通过 WebSocket 实现服务器主动向客户端推送消息,确保监控系统能够实时反映设备状态的变化。通过一个简单的示例,我们将实现一个消防设备巡检系统,后台服务可实时向前端页面发送设备异常信息,并通过 WebSocket 将这些信息推送到监控页面,实时更新设备状态。
整体架构
在本项目中,我们采用 Spring Boot 作为后端开发框架,结合 WebSocket 实现实时消息推送。前端则使用 Vue 和 Element,并通过 WebSocket 与后端建立实时通信连接。当设备发生异常时,前端会根据 WebSocket 推送的数据动态更新设备状态。
项目结构
前端: 基于 Vue 和 Element 实现的设备巡检页面,用户可以通过页面查看各设备的状态并接收异常信息。后端: 使用 Spring Boot 构建 WebSocket 服务端,并通过 @ServerEndpoint 注解创建 WebSocket 连接,实现与客户端的实时消息推送。
实现步骤
配置 Spring Boot WebSocket 服务端配置 application.yml 配置文件
复制
# application.yml 配置
server:
port: 18801
mySocket:
myPwd: jae_123 # WebSocket 密码校验1.2.3.4.5.6.7.
WebSocket 配置类
在 Spring Boot 项目中,我们需要创建一个配置类来启用 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 {
/**
* 注入一个 ServerEndpointExporter, 该 Bean 会自动注册使用 @ServerEndpoint 注解声明的 WebSocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.
WebSocket 服务端类
WebSocket 服务端类负责处理客户端连接、消息发送和关闭连接等操作。
复制
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();
}
}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.
WebSocket Controller 处理前端请求
控制器类负责接收来自客户端的请求,并通过 WebSocket 向所有连接的客户端广播消息。
复制
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); // 广播异常设备ID
}
}
}1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.
前端实现:Vue + WebSocket
前端页面采用 Vue 和 WebSocket 进行实时通信。
前端 HTML 和 Vue 代码
复制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>实时监控</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); // 服务端发过来的消息,ID,string需转化为int类型才能比较
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已关闭");
};
webSocket.onerror = function () {
console.log("websocket发生了错误");
};
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>1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.
测试与结果打开前端页面: 在浏览器中打开监控页面,WebSocket 会自动连接服务器并输出连接成功的日志。提交异常数据: 使用 Postman 等接口测试工具向后端发送设备异常数据,设备 ID 为 3 的设备状态会变为红色(表示异常)。
结论
通过 Spring Boot 和 WebSocket 的结合,成功实现了一个实时监控系统。在这个系统中,服务端能够主动向客户端推送消息,确保监控数据实时更新。利用 WebSocket 技术,我们可以实现高效、稳定、低延迟的实时通信,使得设备异常能够快速传递到监控平台,提高工作效率和安全性。这种基于 WebSocket 的实时监控方案,不仅适用于设备巡检场景,还可以扩展应用到其他需要实时反馈的系统中。
通过本文的实践,我们可以看到 WebSocket 在实时通讯中的强大能力,使用 Spring Boot 构建的 WebSocket 服务端具备了良好的扩展性和稳定性,非常适合处理这种实时性要求较高的业务场景。