Real‑Time Monitoring System Using WebSocket with SpringBoot and Vue
This article demonstrates how to build a real‑time equipment‑monitoring solution by using WebSocket for server‑to‑client push, with a SpringBoot backend that handles WebSocket connections and a Vue.js front‑end that visualizes device status and updates instantly when an abnormal event is reported.
The author describes a requirement where fire‑equipment inspections trigger abnormal alerts that must be pushed to a monitoring page and displayed on a map, prompting staff to handle the issue.
Because the server needs to actively send messages to the client, WebSocket is chosen as the communication protocol.
Front‑end implementation (Vue.js):
<!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 = null;
if ('WebSocket' in window) {
webSocket = new WebSocket("ws://localhost:18801/webSocket/" + getUUID());
webSocket.onopen = function(){ console.log("已连接"); webSocket.send("消息发送测试"); };
webSocket.onmessage = function(msg){
var serverMsg = msg.data;
var t_id = parseInt(serverMsg);
for (var i=0;iBackend implementation (SpringBoot):
# application.yml
server:
port: 18801
mySocket:
myPwd: jae_123 @Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
} @ServerEndpoint("/webSocket/{uid}")
@Component
public class WebSocketServer {
private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
private static final AtomicInteger onlineNum = new AtomicInteger(0);
private static CopyOnWriteArraySet
sessionPools = new CopyOnWriteArraySet<>();
@OnOpen
public void onOpen(Session session, @PathParam("uid") String uid){
sessionPools.add(session);
onlineNum.incrementAndGet();
log.info(uid + "加入webSocket!当前人数为" + onlineNum);
}
@OnClose
public void onClose(Session session){
sessionPools.remove(session);
int cnt = onlineNum.decrementAndGet();
log.info("有连接关闭,当前连接数为:{}", cnt);
}
public void sendMessage(Session session, String message) throws IOException {
if(session != null){
synchronized (session){
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){
log.error("发生错误");
throwable.printStackTrace();
}
} @RestController
@RequestMapping("/open/socket")
public class WebSocketController {
@Value("${mySocket.myPwd}")
public String myPwd;
@Autowired
private WebSocketServer webSocketServer;
@PostMapping("/onReceive")
public void onReceive(String id, String pwd) throws IOException {
if(pwd.equals(myPwd)){
webSocketServer.broadCastInfo(id);
}
}
}The testing steps include opening the front‑end page to establish the WebSocket connection, using Postman to POST an abnormal device ID, and observing the UI change (the device row turns red) to confirm real‑time push works.
Finally, the author invites readers with similar real‑time monitoring needs to refer to the example.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.