websocket 全局监听,切换页面不新添加服务,断网可以重连。不做全局监听,vue路由切换可能会同时添加多个服务,频繁发送消息。服务器压力过大。
1.新建一个js文件在静态文件夹下面 websocket.js
export default class WebSocketManager {
constructor(url = null, receiveMessageCallback = null) {
this.socket = null // WebSocket 对象
this.pingTimeout = null // 心跳计时器
this.reconnectTimeout = null //重联计时器
this.reconnectTimeoutClock = 5000 // 重连间隔,单位:毫秒
this.maxReconnectAttempts = 10 // 最大重连尝试次数
this.reconnectAttempts = 0; // 当前重连尝试次数
this.url = url // WebSocket 连接地址
this.receiveMessageCallback = receiveMessageCallback // 接收消息回调函数
}
/**
* 初始化
*/
async start() {
if (this.url) {
// 连接WebSocket
this.connectWebSocket()
} else {
console.error('WebSocketerros: 请传入连接地址')
}
}
/**
* 创建WebSocket连接
*/
connectWebSocket() {
// 创建 WebSocket 对象
this.socket = new WebSocket(this.url)
// 处理连接打开事件
this.socket.addEventListener('open', event => {
console.log('connet order websocket')
// 心跳机制
this.startHeartbeat()
})
// 处理接收到消息事件
this.socket.addEventListener('message', event => {
this.receiveMessage(event)
})
// 处理连接关闭事件
this.socket.addEventListener('close', event => {
// 清除定时器
clearTimeout(this.pingTimeout)
clearTimeout(this.reconnectTimeout)
// 尝试重连
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++
this.reconnectTimeout = setTimeout(() => {
this.connectWebSocket()
}, this.reconnectTimeoutClock)
} else {
// 重置重连次数
this.reconnectAttempts = 0
console.error('已达到最大重新连接尝试次数。无法重新连接。')
}
})
// 处理 WebSocket 错误事件
this.socket.addEventListener('error', event => {
console.error('WebSocket order error:', event)
})
}
/**
* 启动心跳机制
*/
startHeartbeat() {
this.pingTimeout = setInterval(() => {
// 发送心跳消息
this.sendOrderMessage('heartCheck')
}, 15000) // 每隔 10 秒发送一次心跳
}
/**
* 发送消息
* @param {String} message 消息内容
*/
sendOrderMessage(message) {
console.log('发送的消息',message)
if (this.socket.readyState === WebSocket.OPEN) {
this.socket.send(message);
} else {
console.error('error: WebSocket连接未打开,无法发送消息。')
}
}
/**
* 接收到消息
*/
receiveMessage(event) {
// 根据业务自行处理
console.log('receiveMessage:', event.data)
// 传入回调函数自行处理
this.receiveMessageCallback && this.receiveMessageCallback(event.data)
}
/**
* 关闭连接
*/
closeWebSocket() {
this.socket.close()
// 清除定时器 重置重连次数
clearTimeout(this.pingTimeout)
clearTimeout(this.reconnectTimeout)
this.reconnectAttempts = 0
}
}
2.在mian.js里面 注册实例
//根据情况添加
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
import store from './store'
import $ from 'jquery'
// 创建WebSocket实例
import WebSocketManager from './utils/websocket.js';//websocket地址引入
//用于监听返回消息,页面处理
const messageBack = (msg) => {
// 设置storage值
store.commit('setOrderStatus', msg);//同步操作
}
const socket = new WebSocketManager('wss://xxxx',messageBack);
Vue.prototype.$socket = socket
//在create里面启动
new Vue({
router,
store,
render: h => h(App),
created() {
socket.start()
}
}).$mount('#app')
3. 在store 里面添加状态管理
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
orderStatus:'0',//默认未支付
},
mutations: {
setOrderStatus(state, newId) {
state.orderStatus = newId;
},
},
actions: {
updateOrderStatus({ commit }, newId) {
commit('setOrderStatus', newId);
}
},
modules: {},
getters: {
orderStatus: state => state.orderStatus
},
})
export default store
4.vue 页面应用 可以发送消息,接收消息和进行消息处理
//发送消息的写法
this.$socket.sendOrderMessage(msg);
<script>
export default {
computed: {
storage() {
return this.$store.getters.orderStatus;
}
},
//监听返回值的变化,用于页面逻辑处理
watch: {
storage(newValue, oldValue) {
// 当storage值变化时,这个函数会被调用
console.log('Storage value changed:', newValue);
var orderMsg = newValue
// 检查键是否匹配,根据实际情况修改,这里的1是获取到的newValue值
if(orderMsg == 1){
//这个方法逻辑处理,处理页面需要操作的东西
this.messageOrderBack(orderMsg)
}
}
},
methods: {
//接收到新的消息 --处理页面返回数据操作详情
messageOrderBack(msg){
console.log('收到的消息',msg);
if(msg == "1"){
111
}else{
//心跳测试不需要反馈
}
},
},
}
<script>