用websocket给前端大屏实时推送数据

目前我想实现Java后台用websocket推送大屏数据到vue前端,后台用的是微服务springboot,大屏的数据截图如下:

img

之前是前端调后台接口实现的,但客户反映实时性不高,所以想用websocket来实现实时推送数据

能提供一些资料或简单容易上手的教程,谢谢

你是想问java使用websocket的教程 还是 前端使用 websocket的教程?

如果是我的话,其实node+vue前端就能非常简单的解决socket长连接的传输问题了

Websocket是一种在单个TCP连接上提供双向通信的协议,它可以实现实时推送数据,这使得它非常适合用于实时通信应用程序。以下是使用Websocket实现实时推送数据的步骤:

  1. 前端先要创建一个WebSocket对象,指定服务器的URL地址:
let ws = new WebSocket('ws://example.com');
  1. 当WebSocket连接成功时,前端可以发送消息到服务器,也可以接收来自服务器的消息。通过监听WebSocket对象的onopen、onmessage、onclose和onerror事件,我们可以处理这些事件:
ws.onopen = function(event) {
  // 连接成功,可以发送消息到服务器
  ws.send('Hello, Server!');
};

ws.onmessage = function(event) {
  // 接收到服务器发送的消息
  console.log('Received message: ' + event.data);
};

ws.onclose = function(event) {
  // 连接关闭
  console.log('Connection closed');
};

ws.onerror = function(event) {
  // 发生错误
  console.log('Error: ' + event.data);
};
  1. 如果需要向服务器发送数据,可以使用WebSocket对象的send方法:
ws.send('Hello, Server!');
  1. 如果服务器有更新的数据需要推送给前端,可以将数据发送给前端客户端。前端通过监听WebSocket对象的onmessage事件来接收来自服务器的数据:
ws.onmessage = function(event) {
  // 解析服务器发送的数据
  let data = JSON.parse(event.data);

  // 处理数据,更新UI
  updateUI(data);
};
  1. 在服务器端,如何实现在数据更新时向所有连接的客户端推送数据呢?可以使用Websocket的广播机制。当数据更新时,服务器可以遍历所有连接的客户端,将数据发送给每个客户端:
def broadcast(message):
    for ws in websockets:
        ws.send(message)
  1. 在服务器端,如何处理来自客户端的消息呢?可以在服务器端编写WebSocket的处理程序:
async def ws_handler(websocket, path):
    # 添加客户端连接
    websockets.add(websocket)

    try:
        # 处理消息
        async for message in websocket:
            # 广播消息到所有客户端
            broadcast(message)
    finally:
        # 客户端连接断开,移除客户端
        websockets.remove(websocket)

这是一个简单的WebSocket服务器示例,它使用Python的asyncio库实现:

import asyncio
import websockets

# 保存连接的WebSocket客户端
websockets = set()

async def ws_handler(websocket, path):
    # 添加客户端连接
    websockets.add(websocket)

    try:
        # 处理消息
        async for message in websocket:
            # 广播消息到所有客户端
            broadcast(message)
    finally:
        # 客户端连接断开,移除客户端
        websockets.remove(websocket)

def broadcast(message):
    for ws in websockets:
        ws.send(message)

async def main():
    async with websockets.serve(ws_handler, "localhost", 8080):
        await asyncio.Future()  # run forever

if __name__ == '__main__':
    asyncio.run(main())

以上就是使用Websocket实现实时推送数据的基本步骤。

一个小栗子.
后台:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
@EnableScheduling
public class WebSocketApplication {

    private final SimpMessagingTemplate messagingTemplate;

    public WebSocketApplication(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    public static void main(String[] args) {
        SpringApplication.run(WebSocketApplication.class, args);
    }

    @Controller
    public static class WebSocketController {

        @GetMapping("/")
        public String index() {
            return "index";
        }

        @GetMapping("/send-data")
        @ResponseBody
        public String sendData() {
            // 模拟从后台获取数据
            String data = "Hello Vue!";
            // 使用WebSocket向前端推送数据
            messagingTemplate.convertAndSend("/topic/data", data);
            return "Data sent!";
        }
    }

    @Bean
    public WebSocketHandler webSocketHandler() {
        return new WebSocketHandler();
    }

    @Scheduled(fixedRate = 5000)
    public void sendDataPeriodically() {
        // 模拟定期从后台获取数据
        String data = "Hello Vue!";
        // 使用WebSocket向前端推送数据
        messagingTemplate.convertAndSend("/topic/data", data);
    }
}

前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Example</title>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="/webjars/sockjs-client/1.1.4/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/2.3.3/stomp.min.js"></script>
</head>
<body>
    <div id="app">
        <h1>{{ message }}</h1>
    </div>

    <script>
        const socket = new WebSocket('ws://localhost:8080/ws');
        const stompClient = Stomp.over(socket);

        const app = Vue.createApp({
            data() {
                return {
                    message: ''
                }
            },
            mounted() {
                stompClient.connect({}, () => {
                    stompClient.subscribe('/topic/data', (data) => {
                        this.message = data.body;
                    });
                });
            }
        });

        app.mount('#app');
    </script>
</body>
</html>

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7619493
  • 这篇博客你也可以参考下:java实现实时展示运行日志(1)-springboot + websocket 实现后台主动将日志推送到前端页面
  • 除此之外, 这篇博客: 基于springboot实现websocket的客户端、服务端中的 3、websocket服务端类 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • package com.gjx.server.webserver.server;
    
    import org.springframework.web.bind.annotation.RestController;
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @Author gjx
     * @email 13450753745@163.com
     * @description websocket的服务端类
     * @Date 2019/10/14
     */
    @ServerEndpoint("/serverTest")
    @RestController
    public class WebSocketServer {
    
        /**
         *存放所有的在线客户端
         * */
        private static Map<String, Session> clients = new ConcurrentHashMap<>();
    
        /**
         * 客户端与服务端连接时触发执行事件
         */
        @OnOpen
        public void onOpen(Session session) throws InterruptedException, IOException {
            System.out.println("有新的客户端连接进来了");
            clients.put(session.getId(), session);
        }
    
        /**
         * 向客户端发送字符串信息
         */
        private static void sendMsg(Session session, String msg) throws IOException {
            session.getBasicRemote().sendText(msg);
        }
    
        /**
         *接收到消息后的处理方式,其中包含客户端的普通信息和心跳包信息,
         * 简单区别处理
         */
        @OnMessage
        public void onMessage(Session session, String msg) throws Exception {
    
            if (!msg.equals("keepalive")){
                System.out.println("服务端收到消息:" + msg);
                Thread.sleep(3000L);
                sendMsg(session,msg);
            }else{
                System.out.println("心跳维护包:" + msg);
            }
        }
    
        @OnClose
        public void onClose(Session session) {
            System.out.println("有客户端断开连接了,断开客户为:" + session.getId());
            clients.remove(session.getId());
        }
    
        @OnError
        public void onError(Throwable throwable) {
            System.out.println("服务端出现错误");
            throwable.printStackTrace();
        }
    
    }