告别掉线!SpringBoot+WebSocket打造超稳定实时监控!

干自闭

关注

阅读 1

1天前

点击上方“程序员蜗牛g”,选择“设为星标”跟蜗牛哥一起,每天进步一点点

告别掉线!SpringBoot+WebSocket打造超稳定实时监控!_java

程序员蜗牛g大厂程序员一枚 跟蜗牛一起 每天进步一点点32篇原创内容公众号

本文将结合 SpringBoot + WebSocket 技术,深入探讨如何构建一个超稳定的实时监控系统。

告别掉线!SpringBoot+WebSocket打造超稳定实时监控!_spring_02

实现步骤

配置 Spring Boot WebSocket 服务端

配置 application.yml 配置文件

告别掉线!SpringBoot+WebSocket打造超稳定实时监控!_java_03

在 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();
    }
}

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();
    }
}

控制器类负责接收来自客户端的请求,并通过 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
        }
    }
}

前端页面采用 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>

告别掉线!SpringBoot+WebSocket打造超稳定实时监控!_spring_04


如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

精彩评论(0)

0 0 举报