WebSocket 消息推送
WebSocket消息推送 echarts图表实时刷新
目录
一: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-全局websockethttps://blog.csdn.net/qq_63312957/article/details/125482244?spm=1001.2014.3001.5502。
如果你恰好需要读到这篇文章,希望对你有帮助。如有写的不对或不够好的地方,欢迎指正。
更多推荐
所有评论(0)