要实现的是这样一个需求:
用户选择不同参数后,断开原有的socket连接,并且使用新的参数创建新的socket连接
会报错
字面意思是WebSocket在连接建立之前关闭。
代码:
按理说先关闭再重新打开逻辑上没有什么问题,但是既然报错了就分析一下
分析:socket是基于tcp协议建立的,tcp断开连接需要四次挥手,那么socket断开连接应该也需要这样一个过程,按顺序执行的话,可能就是socket关闭的回调函数还没有执行完毕,就重新init了,就导致报错;
关闭回调执行之前就已经重新打开了,
我的方法是给重新init的函数加了100毫秒的延迟:
// 监听数据变化
watch(props, () => {
console.log('关闭');
stateWsObj?.onclose(); //断开socket连接
setTimeout(() => {
initSocket();
console.log('重新打开');
}, 100);
});
<script lang="ts" setup>
import * as echarts from 'echarts';
import { ref, onMounted, onBeforeUnmount, defineProps, watch } from 'vue';
let socketUrl = configUrl.socketUrl;
// 定义props属性
const props = defineProps({
param: {
type: Object,
// eslint-disable-next-line vue/require-valid-default-prop
default: { entityId: 0, entityParam: '' },
},
});
console.log('entityParam', props.param);
interface WebSocket {
onopen: Function;
onmessage: Function;
onclose: Function;
onerror: Function;
}
let stateWsObj: WebSocket | any;
onMounted(() => {
initSocket(); // 初始化socket
console.log('开始加载图表');
initChart(); // 初始化图表
});
let timeData: any = ref([]); // 时间
let pramsData: any = ref([]); // 参数
let myChart: any = {}; //echarts图表实例
const setDataSource = () => {
myChart.setOption({ xAxis: { data: timeData.value }, series: { data: pramsData.value } });
};
// 监听数据变化
watch(timeData.value, () => {
setDataSource();
});
// 监听数据变化
watch(props, () => {
console.log('关闭');
stateWsObj?.onclose(); //断开socket连接
setTimeout(() => {
initSocket();
console.log('重新打开');
}, 100);
});
const initChart = () => {
const chartDom: any = document.getElementById('main');
myChart = echarts.init(chartDom);
const chartOption = {
tooltip: {
trigger: 'axis',
position: function (pt: any[]) {
return [pt[0], '10%'];
},
},
grid: {
left: '13%',
right: '12%',
bottom: '23%',
},
title: {
left: 'center',
text: '数据监控',
},
toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none',
},
// restore: {},
// saveAsImage: {},
},
},
xAxis: {
type: 'category',
name: '时间戳',
boundaryGap: false,
axisLine: {
symbol: ['none', 'arrow'],
symbolOffset: [0, 15],
},
show: true,
data: [],
},
yAxis: {
type: 'value',
// name: '速度',
boundaryGap: [0, '100%'],
},
dataZoom: [
{
type: 'inside',
start: 0,
end: 10,
},
{
start: 0,
end: 10,
},
],
series: [
{
name: '纬度',
type: 'line',
symbol: 'none',
sampling: 'lttb',
itemStyle: {
color: 'rgb(255, 70, 131)',
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgb(255, 158, 68,0.3)',
},
{
offset: 1,
color: 'rgba(255,58,0,0.5)',
},
]),
},
data: [],
},
],
};
myChart.setOption(chartOption);
};
const initSocket = () => {
//建立连接
//websocket接收 日志数据
stateWsObj =
new WebSocket(`${socketUrl}/pushModelInstance?instanceId=${props.param.entityId}&measure=${props.param.entityParam}
`);
stateWsObj.onopen = function () {
//发送请求
console.log('open');
};
stateWsObj.onmessage = function (ev: any) {
const info = JSON.parse(ev.data);
//获取后端响应
if (Array.isArray(info)) {
// 第一帧 数组
info.forEach((item) => {
timeData.value.push(item.time);
pramsData.value.push(item.data);
});
} else {
timeData.value.push(info.time);
pramsData.value.push(info.data);
}
};
stateWsObj.onclose = function (e) {
console.log(e);
stateWsObj?.close();
};
stateWsObj.onerror = function () {
console.log('error');
};
};
onBeforeUnmount(() => {
stateWsObj?.onclose(); //断开socket连接
});