1、了解webSocket:阮一峰-webSocket教程
2、使用webSocket的方式:
3、组件中使用的代码:
// 可以直接写在App.vue中,数据用vuex存储。我这边是直接写在某个父组件中,因为有些组件不需要用websocket
<template>
<div class="main">
<div class="home">
<!-- 组件A -->
<A :aData="aData"/>
<!-- 组件B -->
<B :bData="bData"/>
<!--组件C -->
<C :cData="cData"/>
</div>
</div>
</template>
<script>
// 引入 A 组件
import A from "./a.vue"
// 引入 B 组件
import B from "./b.vue"
// 引入 C 组件
import C from "./c.vue"
// 引入请求对象(自己封装的)
import request from '@/api/request'
export default {
name: "HomeIndex",
components: {
A,
B,
C
},
data() {
return {
ws_heart: null, // 心跳监测对象
ws: null, // WebSocket实例
connectTimer: null, // 重连对象
aData: {}, // a组件需要的数据
bData: {}, // b组件需要的数据
cData: {}, // c组件需要的数据
}
},
created() {
this.wsInit()
},
// 离开路由之后断开websocket连接
// destroyed() {
// this.ws.close()
// },
methods: {
// 初始化ws
wsInit() {
let wsUrl = "ws://localhost:8000"
//先判断浏览器是否支持WebSocket
if (typeof WebSocket === "undefined") {
alert("您的浏览器不支持socket");
} else {
// 判断 WebSocket是否已经建立连接,避免重复连接
this.ws && this.ws.close()
// 新增一个websocket实例,并且建立连接
this.ws = new WebSocket(wsUrl)
// 连接成功后的回调函数
this.ws.onopen = this.handleWsOpen
// 收到服务器数据后的回调函数
this.ws.onmessage = this.handleWsMessage
// 连接关闭后的回调函数
this.ws.onclose = this.handleReconnectWs
// 报错时的回调函数(网络断开,网络不稳定, 用户电脑休眠)
this.ws.onerror = this.handleReconnectWs
}
},
// ws建立连接
handleWsOpen() {
console.log('websocket已连接,可以进行请求了');
// 开启心跳监测
this.handleHeartListen()
// 发送请求
this.init()
},
// ws拿到服务器(后端接口)或者客户端(心跳监测或者自测)发送的数据
handleWsMessage(msg) {
console.log('onMessage数据-----' + msg)
// 如果因为一些异常断开了连接,我们是不会感应到的,所以开启心跳监测
this.handleHeartListen()
// 拿到的数据
let result = msg.data
if (msg.data instanceof Blob) {
const reader = new FileReader();
reader.readAsText(msg.data, "UTF-8");
reader.onload = (e) => {
result = JSON.parse(e.currentTarget.result)
console.log('???',result)
/**
* 如果拿到的不是客户端自己发送的数据,那么说明就是后端有新数据进行更新,所以需要重新请求
* 或者和后端约定一个固定的数据,如果是这个数据,则不需要重新请求
*/
if(result !== 'self') {
this.init()
}
}
} else {
console.log('不是blob',result)
/**
* 如果拿到的不是客户端自己发送的数据,那么说明就是后端有新数据进行更新,所以需要重新请求
* 或者和后端约定一个固定的数据,如果是这个数据,则不需要重新请求
*/
if(result !== 'self') {
this.init()
}
}
},
// WebSocket的心跳监测,20s进行一次数据的发送,查看是否断开连接(需求是2s...我自测用的20s)
handleHeartListen() {
clearInterval(this.ws_heart)
this.ws_heart = setInterval(() => {
/**
* 自己定义的数据或者和后端约定一个固定的数据
*/
this.ws.send(JSON.stringify("self"));
}, 20000)
},
// 重连ws
handleReconnectWs() {
this.connectTimer && clearTimeout(this.connectTimer);
this.connectTimer = setTimeout(() => {
console.log('重连',this.ws.readyState)
// 接已经关闭,或者打开连接失败
if (this.ws.readyState === 3) {
this.wsInit()
}
}, 20000) // 需求是2s...我自测用的20s
},
// 初始化所有请求
init() {
// 获取A组件的数据
this.getAdata()
// 获取B组件的数据
this.getBdata()
// 获取C组件的数据
this.getCdata()
},
// 获取A组件的数据
getAdata() {
// TODOS: 请求数据,将拿到的数据赋值给aData
},
// 获取B组件的数据
getBdata() {
// TODOS: 请求数据,将拿到的数据赋值给bData
},
// 获取C组件的数据
getCdata() {
// TODOS: 请求数据,将拿到的数据赋值给cData
}
}
}
</script>
4、webSocket中监听客户端数据,收到[object Blob]类型的解决办法:
1)问题截图:
2)解决办法:
方法一:更改package.json中ws的版本号,重新安装ws,重启项目
方法二:对当前的类型进行判断:
this.ws.onmessage = (msg) => {
// 进行心跳监测,如果有新数据,则重新进行请求
console.log('新消息' + msg.data)
if (msg.data instanceof Blob) {
const reader = new FileReader();
reader.readAsText(msg.data, "UTF-8");
reader.onload = (e) => {
console.log('websocked收到', JSON.parse(e.currentTarget.result));
}
}
}