vuex引入全局websocket 用作IM即时通讯(基于uniapp开发的微信小程序即时通讯模块)

最近公司开发的项目管理软件需要加入即时通讯功能,后端基于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');
	}
}

 

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WebIM说明 WebIM是一款基于jQuery的一款web即时通讯插件,姑且这么称呼吧。插件最大程度实现了IM的常用功能,除即时通讯的常用功能外,还加入了:消息盒子、窗口抖动、添加删除好友、最近联系人、超时登录界面、网站小秘书、聊天记录、发送频率限制、发送产品、发送名片、发送表情、产品分享、黑名单、举报、收藏、公告、智能网址过滤、消息提醒、修改资料、名片二维码、禁止粘贴、收起联系人列表、推荐好友等30余项改进。全浏览器兼容。 插件调用简单方便,只需在现有的web系统中加入几行代码,理论上可嵌入任何web系统。 2012年项目,已不再维护。 配置 $(function() { $(document).FnWebIM({ autoLogin :true, //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true msgRefreshTime :1000, //number型,消息刷新时间,单位为ms friendRefreshTime :10000, //number型,好友刷新时间,单位为ms showSecretary :true, //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true noticeContent :"唐僧师徒历经千辛万苦,终于见到了佛祖……", //string型,公告内容 为空时不显示公告 sendPicture :true, //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true msgMaxSize :300, //number型,单条消息最大允许字符 msgSound :false, //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true defaultWindow :"" //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错 }); }); 详细说明文档 http://www.zi-han.net/case/im/help.html 示例 http://www.zi-han.net/developer/721.html 注意 请在服务器(如localhost)环境下打开

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值