vuex引入全局websocket 用作IM即时通讯(基于uniapp开发的微信小程序即时通讯模块)
最近公司开发的项目管理软件需要加入即时通讯功能,后端基于springboot+netty+ws,本人被迫从java开发工程师转型成全栈,如果代码有什么问题欢迎指出后端功能开发参考了github的开源项目 上链接https://github.com/lmxdawn/him-netty前端采用uniapp提供的wsAPI,微信小程序或web端实现思路也是一样的实现ws登录,心跳,断线重连的功...
·
最近公司开发的项目管理软件需要加入即时通讯功能,后端基于springboot+netty+ws,本人被迫从java开发工程师转型成全栈,如果代码有什么问题欢迎指出
后端功能开发参考了github的开源项目 上链接https://github.com/lmxdawn/him-netty
前端采用uniapp提供的wsAPI,微信小程序或web端实现思路也是一样的
实现ws登录,心跳,断线重连的功能
vuex的功能不用多说 不懂的可以先学习一下
在项目根目录下创建文件: /common/websocketStore.js
注释很全就不多作说明了
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
socketTask: null, // ws链接
webSocketPingTimer: null, // 心跳定时器
webSocketPingTime: 10000, // 心跳的间隔,当前为 10秒,
webSocketReconnectCount: 0, // 重连次数
webSocketIsReconnect: true, // 是否重连
webSocketIsOpen: true,
uid: null, //ws登录userId
sid: null, //ws登录token
msg: null //接收到的信息
},
getters: {
// 获取接收的信息
socketMsgs: state => {
return state.msg
}
},
mutations: {
//发送http请求登录后设置用户id 用于ws登录
setUid(state, uid) {
state.uid = uid
},
//发送http请求登录后设置用户token 用于ws登录
setSid(state, sid) {
state.sid = sid
},
//初始化ws 用户登录后调用
webSocketInit(state) {
let that = this
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
state.socketTask = uni.connectSocket({
url: "ws://196.192.168.169:9001/ws",
success(data) {
console.log("websocket连接成功");
},
});
// ws连接开启后登录验证
state.socketTask.onOpen((res) => {
console.log("WebSocket连接正常打开中...!");
that.commit('webSocketLogin')
//开始心跳
that.commit('webSocketPing')
// 注:只有连接正常打开中 ,才能正常收到消息
state.socketTask.onMessage((res) => {
console.log("收到服务器内容:" + res.data);
state.msg = JSON.parse(res.data)
});
});
// 链接开启后登录验证
state.socketTask.onError((errMsg) => {
console.log(errMsg)
console.log("ws连接异常")
that.commit('webSocketClose')
});
// 链接开启后登录验证
state.socketTask.onClose((errMsg) => {
console.log(errMsg)
console.log("ws连接关闭")
that.commit('webSocketClose')
});
},
webSocketLogin() {
let that = this
console.log("ws登录");
const payload = {
uid: that.state.uid,
sid: that.state.sid,
type: 1
};
that.commit('webSocketSend', payload);
that.state.webSocketIsOpen = true
},
// 断开连接时
webSocketClose(state) {
let that = this
// 修改状态为未连接
state.webSocketIsOpen = false;
state.webSocket = null;
// 判断是否重连
if (
state.webSocketIsReconnect &&
state.webSocketReconnectCount === 0
) {
// 第一次直接尝试重连
that.commit('webSocketReconnect');
}
},
// 定时心跳
webSocketPing() {
let that = this
that.state.webSocketPingTimer = setTimeout(() => {
if (!that.state.webSocketIsOpen) {
return false;
}
console.log("心跳");
const payload = {
type: 0
};
that.commit('webSocketSend', payload);
clearTimeout(that.state.webSocketPingTimer);
// 重新执行
that.commit('webSocketPing');
}, that.state.webSocketPingTime);
},
// WebSocket 重连
webSocketReconnect(state) {
let that = this
if (state.webSocketIsOpen) {
return false;
}
console.log("第"+state.webSocketReconnectCount+"次重连")
state.webSocketReconnectCount += 1;
// 判断是否到了最大重连次数
if (state.webSocketReconnectCount >= 10) {
this.webSocketWarningText = "重连次数超限";
return false;
}
// 初始化
console.log("开始重连")
that.commit('webSocketInit');
// 每过 5 秒尝试一次,检查是否连接成功,直到超过最大重连次数
let timer = setTimeout(() => {
that.commit('webSocketReconnect');
clearTimeout(timer);
}, 5000);
},
// 发送ws消息
webSocketSend(state, payload) {
let that = this
that.state.socketTask.send({
data: JSON.stringify(payload),
fail: function(res){
console.log("发送失败")
that.state.sendMsgStatus = true
},
success: function(res){
console.log("发送成功")
that.state.sendMsgStatus = false
}
})
}
},
actions: {
webSocketInit({
commit
}, url) {
commit('webSocketInit', url)
},
webSocketSend({
commit
}, p) {
commit('webSocketSend', p)
}
}
})
在项目根路径main.js下全局引入js
import websocket from '@/common/websocketStore.js'
Vue.prototype.$websocket = websocket;
成功登录的回调方法中设置 uid,sid
let that = this
that.$websocket.commit('setUid',res.data.id)
that.$websocket.commit('setSid',res.data.apiKey)
that.$websocket.dispatch('webSocketInit');//初始化ws
在需要接收消息的页面接受并处理消息
computed: {
//监听接收到的消息
socketMsgs() {
return this.$websocket.getters.socketMsgs
}
},
watch: {
'socketMsgs': {
//处理接收到的消息
handler: function() {
let that = this
console.log("接收到msg")
let sMsg = that.socketMsgs
console.log(sMsg)
}
}
},
app.vue添加代码 实现微信后台心跳失败 重连
//应用生命周期 onShow 当 uni-app 启动,或从后台进入前台显示
onShow: function() {
let that = this
if(that.$websocket.getters.sendMsgStatus){
that.$websocket.dispatch('webSocketInit');
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)