uniapp开发手机app--vuex结合websocket实现全局消息推送提示
最近也开发了自己的公众号,会在上面分享前端方面的知识,有兴趣的话,走个关注吧!!!
在vuex内实现websocket的链接,采用心跳检测的方法来判断是否与服务端失去联系,来控制断线重连,代码比较全面,直接赋值粘贴根据业务调整就可以直接用了
//getuserId方法是用来获取本地缓存里的用户ID的
import { getuserId } from '@/utils/auth'
//导入链接
const socketData = {
state: {
socketTast: null, //socket实例
websocketData: {}, // 存放从后端接收到的websocket数据
webSocketPingTimer: null, // 心跳定时器
webSocketPingTime: 10000, // 心跳的间隔,当前为 10秒,
webSocketReconnectCount: 0, // 重连次数
webSocketIsReconnect: true, // 是否重连
webSocketIsOpen: true, //链接是否在打开
},
mutations: {
setsockTast(state, data) {
state.socketTast = data
},
setWebsocketData(state, data) {
state.websocketData = data
},
setChonglian(state, data) {
state.webSocketReconnectCount = state.webSocketReconnectCount + data
},
setIsOpen(state, data) {
state.webSocketIsOpen = data
},
},
actions: {
websocketInit({ state, dispatch, commit }, ) {
let socketTast = uni.connectSocket({
// url, // url是websocket连接ip
url: `${config.WebSocketBaseUrl}/${getuserId()}`,
success: () => {
console.log('websocket连接成功!')
},
fail: e => {
console.log(e)
}
})
commit('setsockTast', socketTast)
//检测链接打开
state.socketTast.onOpen(() => dispatch('websocketOnOpen'))
//接收服务器消息
state.socketTast.onMessage(res => dispatch('websocketOnMessage', res))
// 链接关闭事件
state.socketTast.onClose(e => dispatch('websocketOnClose'))
//链接错误
state.socketTast.onError(e => dispatch('websocketOnError'))
},
// 定时心跳告诉服务器自己还活着,防止丢包
webSocketPing({ state, dispatch }) {
if (getuserId()) {
state.webSocketPingTimer = setTimeout(() => {
//链接关闭就结束心跳
if (!state.webSocketIsOpen) {
return false;
}
console.log("心跳");
const payload = 1
dispatch('websocketSend', JSON.stringify(payload));
clearTimeout(state.webSocketPingTimer);
// 重新执行
dispatch('webSocketPing');
}, state.webSocketPingTime);
}
},
// 断开连接时
webSocketClose({ state, dispatch, commit }) {
if (getuserId()) {
// 修改状态为未连接
commit('setIsOpen', false)
// state.webSocketIsOpen = false;
state.webSocket = null;
// 判断是否重连
if (
state.webSocketIsReconnect &&
state.webSocketReconnectCount === 0
) {
console.log("正在尝试重连");
// 第一次直接尝试重连
dispatch('webSocketReconnect');
}
}
},
// WebSocket 重连
webSocketReconnect({ state, dispatch, commit }) {
if (getuserId()) {
if (state.webSocketIsOpen) {
return false;
}
console.log("第" + state.webSocketReconnectCount + "次重连")
commit('setChonglian', 1)
// 判断是否到了最大重连次数
// 初始化
console.log("开始重连")
dispatch('websocketInit');
// 每过 5 秒尝试一次,检查是否连接成功,直到超过最大重连次数
let timer = setTimeout(() => {
dispatch('webSocketReconnect');
clearTimeout(timer);
}, 10000);
}
},
websocketOnOpen({ dispatch, commit }) {
console.log('WebSocket连接正常打开中...!')
commit('setIsOpen', true)
//开始心跳检测
dispatch('webSocketPing')
},
// 收到数据
websocketOnMessage({ commit }, res) {
// 修改状态为未连接
//接到推送的消息--显示全局弹窗
if (res.data !== 'sssss' && res.data !== '连接成功') {
// #ifdef APP-VUE
uni.createPushMessage({
title: "任务提醒",
sound: "system",
content: JSON.parse(res.data).messageContent,
success(res) {
console.log('推送成功', res)
},
fail(err) {
console.log('推送失败', err)
}
})
console.log(alarmIns);
// #endif
// #ifdef H5
//弹窗
this._vm.$openInvite(JSON.parse(res.data).messageContent)
// #endif
}
console.log('收到服务器内容:' + res.data.toString().slice(1, 11))
if (res.data !== '连接成功') {
commit('setWebsocketData', (res.data || null))
}
},
websocketOnClose({ commit, dispatch }) {
//链接关闭执行
// dispatch('webSocketClose')
console.log('websocketOnClose连接关闭')
},
websocketOnError({ commit, dispatch }) {
//链接关闭执行
dispatch('webSocketClose')
console.log('websocketOnError连接错误')
},
//关闭websocket
websocketCloseGuanBi({ state }) {
if (!state.socketTast) return
state.socketTast.close({
success(res) {
console.log('关闭成功', res)
},
fail(err) {
console.log('关闭失败', err)
}
})
},
// 发送数据
websocketSend({ state, dispatch }, data) {
state.socketTast.send({
data,
success: res => {
console.log('发送成功', res)
},
fail: e => {
console.log('发送失败', e)
dispatch('webSocketClose')
}
})
}
}
}
export default socketData