目录

一:SpringBoot后端建立WebSocket服务器 

二:前端vue页面 使用echarts和WebSocket

三:服务端给客户端推送消息

四:注意


一:SpringBoot后端建立WebSocket服务器 

1.SpringBoot使用WebSocket准备

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.WebSocketConfig 注入ServerEndpointExporter 交给spring容器管理

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3.创建WebSocketServer实体类 添加 @ServerEndpoint注解 value 即是前端访问的接口

因为使用websocket的目的只是做消息推送,所以使用了set存储客户端的连接。如果是需要将消息推送给指定客户端,建议使用map或redis将客户端和session绑定存储。

我的代码如下

@Slf4j
//@ServerEndpoint("/api/websocket/{user}")   根据自己的需求选择合适的
@ServerEndpoint(value = "/api/websocket")
@Component
public class WebSocketServer {

    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

//    private static Map<String , Session> sessionMap = new ConcurrentHashMap<>();

    private Session session;

   // 连接建立成功调用的方法
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);
        addOnlineCount();
        try {
            sendMessage("连接成功");
        } catch (IOException e) {
           e.printStackTrace();
        }
    }

    // 此方法是将用户与对应session绑定,用于推送消息给指定用户
    //	@OnOpen
    //	public void onOpen(@PathParam("user") String user, Session session) {
    //		currentUser = user;
    //		System.out.println("Connected ... " + session.getId());
    //	}

    //连接关闭调用的方法
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
    }


    //接收客户端消息
    // @OnMessage
    // public void onMessage(String message, Session session) {
    //    log.info(message);
    // }

    
    //
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    //将消息推送给所有客户端
    public void sendInfo(String message) throws IOException {
        log.info(message);
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }
}

二:前端vue页面 使用echarts和WebSocket

        echarts的使用在此就不再赘述了,不了解的话,可以点击 vue使用echarts

        npm install nodejs-websocket 引入webcoket 

        main.js中引用

import websocket from 'vue-native-websocket';

Vue.use(websocket, '', {
    connectManually: true, // 手动连接
    format: 'json', // json格式
    reconnection: true, // 是否自动重连
    reconnectionAttempts: 5, // 自动重连次数
    reconnectionDelay: 2000, // 重连间隔时间
});

        websocket的使用主要就是初始化一个websocket实例,定义连接路径即请求后端的接口路径,之后就是绑定该websocket的onopen,onerror,onmessage,onsend,onclose方法,知名见意分别是连接成功之后执行的方法(onopen),错误异常时执行(onerror),接收到后端推送的消息时(onmessage),前端向后端发送消息时(onsend),连接关闭时(onclose)。其中onsend,onclose未在代码中使用,其使用方法与其他方法类似,全部代码如下:

<template>
	<div>
	<div id="chart" style="width: 700px; height: 200px;"></div>
	</div>
</template>

<script>
	export default{
		name:"chart",
		data(){
			return{
				scoket:'',
				yAxis:[],
				xAxis:[],
			}
		},
		mounted() {
			this.chart();
			this.init();
		},
		methods:{
           //初始化websocket实例
          init: function () {
            if(typeof(WebSocket) === "undefined"){
              alert("您的浏览器不支持socket")
            }else{
              // 实例化socket
              this.socket = new WebSocket("ws://192.168.1.21:8082/api/websocket")
              // 监听socket连接
              this.socket.onopen = this.open
                // 监听socket错误信息
              this.socket.onerror = this.error
              // 监听socket消息
              this.socket.onmessage = this.getMessage
            }
          },
          open: function () {
            console.log("socket连接成功")
          },
          error: function () {
            console.log("连接错误")
          },
        //接收服务器发来的消息
         getMessage: function (e) {
            console.log(e.data);
            this.xAxis = JSON.parse(e.data).xAxis;
            this.yAxis = JSON.parse(e.data).yAxis;
            this.chart();
          },
          //给服务器发消息的方法
          send: function () {
            this.socket.send(this.parms);
          },
          close: function () {
            console.log("socket已经关闭")
          },
          chart(){
         //有的话就获取已有echarts实例的DOM节点。
      var mychart = this.$echarts.getInstanceByDom(document.getElementById('timechart')); 
             if (mychart == null) { // 如果不存在,就进行初始化。
                 mychart = this.$echarts.init(document.getElementById('chart'));
             }
        var option = {
          title: {
            text: '时间(ms)/阶段'
          },
          tooltip: {
            trigger: 'axis'
          },
          legend: {
            // data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
          },
          toolbox: {
            feature: {
              saveAsImage: {}
            }
          },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            data: this.xAxis
          },
          yAxis: {
            type: 'value'
          },
          series: [
            {
              type: 'line',
              stack: 'Total',
              data: this.yAxis
            }
          ]
        };
        mychart.setOption(option);
      }
    
	}
</script>

<style>
</style>

三:服务端给客户端推送消息

springboot中使用@Autowired注入WebSocketServer

@Autowired
private WebSocketServer webSocketServer;

需要发消息时  

 webSocketServer.sendInfo(JSONObject.toJSONString(chartValue));

四:注意

在发送信息的时候,建议转成JSON格式

 客户端接收的时候要转换一下

根据个人习惯,echarts根据数据更新自动刷新,我喜欢这样写,图表不更新的时候可以尝试一下

获取到服务器的数据之后

在检查中会有json异常错误,不影响

这样写websocket是在该页面实例化一个websocket,每次刷新页面或者重新进入该页面都会新建一个websocket实例,在真实业务中很少会这样处理。所以就需要将websocket定义为全局实例,跟随vue实例的创建而创建,销毁而销毁。

需要vue使用全局websocket的朋友,可以移步 Vue-全局websocketicon-default.png?t=M5H6https://blog.csdn.net/qq_63312957/article/details/125482244?spm=1001.2014.3001.5502

 如果你恰好需要读到这篇文章,希望对你有帮助。如有写的不对或不够好的地方,欢迎指正。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐