最近公司要用websocket 搞一个大屏可视化,找了许多案例才弄明白
import { getToken } from '@/utils/auth'
export default class SocketServer {
// 定义单例(单个实例)模式
static instance = null
static get Instance() {
if (!SocketServer.instance) {//防止创建多个实例对象
SocketServer.instance = new SocketServer()
}
return SocketServer.instance
}
// 和服务端连接的socket对象
ws = null
// 存储回调函数
callBackMapping = {}
// 标识是否连接成功
connection = false
// 记录重试的次数
sendRetryCount = 0;
// 重新连接尝试的次数
connectRetryCount = 0;
// 定义连接服务器的方法
connect() {
// 连接服务器
if (!window.WebSocket) { return console.log('您的浏览器不支持WebSocket') }
this.ws = new WebSocket("ws://xxxxx) // 链接地址
// 连接成功的事件
this.ws.onopen = () => {
console.log("连接socket成功")
this.connection = true
// 重置重新连接的次数
this.connectRetryCount = 0
}
// 失败有两种情况:1.本身连接服务器失败2.连接成功后,关闭了服务器
this.ws.onclose = () => {
console.log('连接关闭')
this.connection = false
this.connectRetryCount++;
setTimeout(() => {
this.connect()
}, 500 * this.connectRetryCount)
}
// 得到服务端发送过来的数据
// 使用箭头函数不会改变callback的this,使callback的this指向vm
this.ws.onmessage = msg => {
// 真正服务端发送过来的原始数据时在msg中的data字段
// console.log(msg.data)
let data = JSON.parse(msg.data)
let socketType = data.tag
// 判断回调函数是否存在
// 根据页面传递的值进行判断
if (socketType == "refreshFirst") {
let realData = data.data
this.callBackMapping[socketType].call(this,realData)
}
else if (socketType == "refreshSecond") {
this.callBackMapping[socketType].call(this,data)
}
else if (socketType == "refreshRoll") {
this.callBackMapping[socketType].call(this,data)
}
}
this.ws.onerror = function () {
console.log('连接异常')
this.connection = false
}
}
// 回调函数的注册
registerCallBack(socketType, callBack) {
this.callBackMapping[socketType] = callBack
}
// 取消某一个回调函数
unRegisterCallBack(socketType) {
this.callBackMapping[socketType] = null
}
// 发送数据的方法
send(data) {
console.log(data);
// 判断此时此刻有没有连接成功
// 连接服务器也需时间,如果先执行发送数据的函数就会报错,用重发机制解决
console.log(this.connection);
if (this.connection == true) {
// 连接上服务器了,重置发送数据给服务器的次数
this.sendRetryCount = 0;
this.ws.send(data)
} else {
// 重发数据机制
// 等待一段时间再次发送
// 若是服务器关闭,仍然采用500ms重连一次不合适,应该延长多少时间间隔重连一次。这样就不会太浪费时间资源
this.sendRetryCount++;
setTimeout(() => {
this.ws.send(data)
}, this.sendRetryCount * 500)
}
}
}
在min.js中全局引入,在项目启动时直接进行连接
// 引入socket
import SocketServer from "./utils/SocketServer"
SocketServer.Instance.connect()
Vue.prototype.$socket = SocketServer.Instance
在页面中的使用
created() {
// 获取websocket数据
this.$socket.registerCallBack('refreshFirst', this.tempData)
},
// 页面关闭时进行销毁
destroyed() {
this.$socket.unRegisterCallBack('refreshFirst')
},
methods: {
tempData(data) {
console.log('获取数据', data);
},
}