uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一

这篇具有很好参考价值的文章主要介绍了uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概要

前端小伙伴使用uni-app开发长连接通信的时候都会有以下疑问

  • 在网上搜到的封装socket都没讲怎么全局公用一个呢?
  • 同一个 子协议或者我我们叫type类型型我想在两个页面都接受使用怎么做呢?

目前能搜到的socket 封装好像都没讲清楚这个东西,或者压根没考虑
下面给大家详细介绍下我封装的方法 大家拿去就可以用。代码在最后了

初始化 创建连接

  • 在合适的场景下创建 Socket 连接
  • 初始化后所有页面均可使用
import socket from "@/components/lvSocket.js"
onLoad(()=>{ // 假设在onLoad周期需要初始化
	socket.connect();// 初始化 全局只需初始化一次
})
onUnload(()=>{
	socket.clearClose();// 关闭长连接根据需要使用
})

接收事件

注意 type等于all时接收所有类型参数

import socket from "@/components/lvSocket.js"

onLoad(()=>{ // 假设在onLoad周期需要初始化
	// 发送消息
	socket.send({
		"type": "msgList",// 传输类型 
		"payLoad": {传输内容}
	});
	socket.on("hei",shjian);// type=hei:接受hei类型参数
	socket.on("hei",()=>{console.log('hei收到了')});// type=hei:接受hei类型参数
	socket.on("heier",()=>{console.log('er收到了')});// type=heier:接受hei类型参数
	socket.on("all",jieshouAll);// type=all:接受所有参数 all为type类型关键字
})

const shjian = (meg)=>{
	console.log('页面收到hei数据',meg)
}

const jieshouAll = (meg)=>{
	console.log('服务端返回的所有数据都能接收到',meg)
}

// 页面卸载清除事件回调
onUnload(()=>{
	socket.off();// 清空所有回调
	socket.off('hei');// 清除某个类型所有回调
	socket.off('hei',jieshou);// 清除某个类型中某个回调
})

示例

在两个页面 接受同一个类型 也是互不影响的。 清除的时候别误删了其他事件哦

import socket from "@/components/lvSocket.js"
// index 页面
	onLoad(()=>{
		socket.connect();// 初始化 全局只需初始化一次
		socket.on("hei",jieshou);// type=hei:接受hei类型参数
		socket.on("all",jieshouAll);// type=all:接受所有参数 all为type类型关键字
	})
	
	const jieshou = (meg)=>{
		console.log('页面收到数据',meg)
		socket.send({type:"pingaaaaa"});// 发送消息
	}
	const jieshouAll = (meg)=>{
		console.log('服务端返回的所有数据都能接收到',meg)
	}
	
	// 页面卸载清除事件回调
	onUnload(()=>{
		socket.off();// 清空所有回调
		socket.off('hei');// 清除某个类型所有回调
		socket.off('hei',jieshou);// 清除某个类型中某个回调
		socket.clearClose();// 关闭长连接根据需要使用
	})
	
// home页面
	onLoad(()=>{
		socket.on("bookList",getBookList);// 接受参数
	})
	
	const getBookList = (meg)=>{
		console.log('页面收到数据',meg)
	}
	
	// 页面卸载清除事件回调
	onUnload(()=>{
		socket.off('bookList');// 清除某个类型所有回调
	})
	

js代码

在 src/components 路径下创建 lvSocket.js 粘贴如下代码到文件中
vue2使用请注意this指向问题

/*
	假设后端响应数据类型是这样的
	{ 
		type:'msglist',
		"payload":{
			... 数据在这里
		}
	}
	*/
/***
* @description: WebSocket 单例模式
* @author: lvhao
*/
class Socket {
	constructor() {
		this.socket = null;// socket实例
		this.isConnect = false;// 是否连接成功
		this.reconnectCount = 0;// 重连接次数
		this.reconnectTimer = null;// 重连定时器
		this.url = `ws://192.168.28.38:3000`
		this.isHandClose = false;// 是否是手动关闭
		
		// 心跳定时器
		this.heartbeatInterval = null;
		
		// 收集事件绑定类型
		this._map = new Map();
		
		// 收集未连接成功要发送的消息
		this._sendArr = [];
		
	}
	// 连接
	connect() {
		if (this.socket) return;// 正在连接
		const Token = uni.getStorageSync('Token');
		this.socket = uni.connectSocket({
			url:this.url,
			header: {
				"wsToken": `Bearer ${Token}`,
			},
			complete: ()=> {},
			multiple:true,
		})
		
		// 连接成功
		this.socket.onOpen(()=>{
			console.log("连接成功")
			this._onOpen();
		})
		// Socket 连接关闭事件
		this.socket.onClose(() => {
			console.log("连接关闭了")
			this._onClose();
		});
		// 监听 Socket 错误事件
		this.socket.onError((err) => {
			console.log("Socket报错了",err)
			this._onError();
		});
		// 监听 WebSocket 接受到服务器的消息事件
		this.socket.onMessage((meg)=>{
			this._onMessage(meg)
		});
		
	}
	
	// 连接成功 重置参数
	_onOpen() {
		this.isConnect = true;// 是否连接成功
		this.reconnectCount = 0;// 重置重连次数
		clearTimeout(this.reconnectTimer);// 清空重连定时器
		this.isHandClose = false;// 是否是手动关闭
		this._heartbeat();// 开启心跳
		
		// 未发送的消息全部发送
		this._sendArr.forEach(item=>{
			this.send(item);// 发送消息
		})
		this._sendArr = [];
	}
	
	// 监听 WebSocket 连接关闭事件
	_onClose() {
		this.socket = null;// 清空soket
		this.isConnect = false;// 是否连接成功
		this._clearHeartbeat();// 关闭心跳
		this._reconnect();// 重新连接
	}
	
	// 监听 WebSocket 错误事件
	_onError() {
		
	}
	
	// 监听 WebSocket 接受到服务器的消息事件
	_onMessage(meg) {
		let data = JSON.parse(meg.data);// 收到的数据
		let receiveType = data.type;// 收到的type类型
		// 触发对应type类型事件  接受type为all时所有事件都会触发
		for (let entry of this._map.entries()) {
			if(entry[1] === receiveType || entry[1] === 'all' ){
				entry[0](data.payLoad)
			}
		}
	}
	
	// 自动重连
	_reconnect() {
		if(this.isHandClose)return;// 手动关闭不重连
		if(this.socket)return;// 正在连接不处理
		if (this.reconnectCount < 10) {
			this.reconnectCount++;
			this.reconnectTimer = setTimeout(() => {
				console.log(`WebSocket 重连中,第 ${this.reconnectCount} 次尝试...`);
				this.connect();//连接
			}, 5000);
		} else {
			console.log('WebSocket 重连失败!');
		}
	}
	
	// 开启心跳
	_heartbeat(){
		this._clearHeartbeat();// 关闭心跳
		// 心跳10000ms发送一次
		this.heartbeatInterval = setInterval(()=>{
			this.send({type:'ping', "payLoad": {"ts": new Date().getTime()}})//心跳内容
		},10000)
	}
	
	// 关闭心跳
	_clearHeartbeat(){
		clearInterval(this.heartbeatInterval)
	}
	
	// 发送消息
	send(data) {
		// 当前未连接记录内容 队列中没有才放入 心跳除外
		if(!this.isConnect && data.type !== "ping" ){
			const hasEqualItem = this._sendArr.some(item => JSON.stringify(item) == JSON.stringify(data));
			if (!hasEqualItem) {
				this._sendArr.push(data);
			}
			return;
		}
		this.socket.send({'data':JSON.stringify(data)});
	}
	
	// 接受信息  type 类型  fn 回调函数
	on(type,fn=()=>{}){
		this._map.set(fn,type);
	}
	
	// 关闭接受参数
	off(type,fn){// 关闭参数
		if(arguments.length === 0){
			// 清除全部
			this._map.clear();
		}else if(arguments.length === 1){
			// 清除某个事件类型整体
			this._map.forEach((value, key) => {
				if (value === type) {
					this._map.delete(key);
				}
			});
		}else{
			// 清除某个事件类型中某个回调
			if(this._map.get(fn) === type){
				this._map.delete(fn)
			}
		}
	}
	
	// 关闭
	clearClose() {
		this.isHandClose = true;// 手动关闭
		clearTimeout(this.reconnectTimer);// 清空重连定时器
		if(this.socket && "close" in this.socket){
			this.socket.close(); // 关闭soket
		}
	}
	
}

export default new Socket()

自定义修改说明

  • 后端参数
    代码开头有提到默认后端给到的数据为
    { 
    	type:'msglist',// 你和后端定义的数据type类型
    	"data":{
    		"key":"value",// 这个type类型对应的数据
    		...
    	}
    }
    如果数据有修改。修改_onMessage函数修改传入你们定义的数据即可
    
  • 心跳
    修改代码中_heartbeat函数 修改心跳内容和心跳间隔时间即可
    
  • 重连
    默认最多重连1010次都失败就不会重新连接了
    默认重连间隔时间5秒
    只有连接失败 或者服务报错才会重新连接  我们手动关闭连接是不会重新连接的放心使用
    修改_reconnect函数中的10 为你想要的重连次数
    修改_reconnect函数中的5000 为你想要的重连间隔时间
    

小结

可以根据自己的需要对其进行魔改。 不懂的地方可以联系我帮大家答疑。v:H1274714546
欢迎有更好方案的小伙伴评论。分享转载,请注明来源哦~文章来源地址https://www.toymoban.com/news/detail-543478.html

到了这里,关于uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uni-app实现点击显示隐藏列表,兼容微信小程序

    效果:    小程序打印的结果:值一直为true   如果你试过v-if不生效,又试了v-show,还是不行!!千万不要着急! 不是自己写的不对,而是uni-app和微信小程序修改值的方式不一致造成的。反正就是不承认是自己的问题。 其实解决的办法也很简单,就是要兼容两端,写出符合

    2024年02月09日
    浏览(44)
  • uni-app实现自定义导航栏,兼容H5、App、微信小程序

    很多情况下,系统自带的导航栏无法满足UI设计的要求,这时候就需要我们自定义导航栏来实现需求,要考虑跨端的多种情况,这里我们封装成一个组件来使用,实现效果如下: 一、H5、App、微信小程序的区别 1.H5:导航栏高度可以设为44px,它没有状态栏,因为H5端运行在浏览

    2024年04月13日
    浏览(38)
  • Uni-app实现左右滑动页面内容切换(兼容微信小程序)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档         前言         整体思路         一、HTML部分         二、Script部分         三、Style部分           (先声明哦我可不是偷懒,只是想学术借鉴一下)因为最近有在做左右滑动功能,

    2024年02月07日
    浏览(55)
  • uni-app Vue3实现一个酷炫的多功能音乐播放器支持微信小程序后台播放

    本文存在多张gif演示图,建议在 wifi 环境下阅读📖 最近在做网易云音乐微信小程序开源项目的时候,关于 播放器功能 参考了一些成熟的微信小程序,如 网易云音乐小程序 和 QQ音乐小程序 ,但是发现这些 小程序端 的播放器相对于 APP端 来说较简单,只支持一些基础功能,

    2024年01月24日
    浏览(43)
  • uni-app 微信小程序蓝牙模块的解耦封装-持续更新

    core.js tool.js util.js main.js

    2024年03月27日
    浏览(77)
  • 【微信小程序】使用uni-app——开发首页搜索框导航栏(可同时兼容APP、H5、小程序)

    目录 前言 App、H5效果 小程序效果 一、兼容APP、H5的方式 二、兼容小程序 三、实现同时兼容 首页都会提供一个搜索框给到客户,让客户自己去搜索自己想要的内容,这里就需要导航栏,来实现搜索页面的跳转,效果如下 在常见titleNView配置代码示例中可以看到基本样式的代码

    2024年02月03日
    浏览(39)
  • 语法速通 uni-app随笔【uni-app】【微信小程序】【vue】

    其中, pages 目录/ index 目录【必有】: index.js 编写业务逻辑 【初始数据,生命周期函数】 index.json 编写配置 index.wxml 编写模板 【可理解为本页html】 index.wxss 【可理解为本页css】 直接输入敲回车,连尖括号都不需要就可以标签补全 1)初始数据写死 在 index.wxml 引入变

    2024年02月12日
    浏览(76)
  • uni-app开发微信小程序 vue3写法添加pinia

    使用uni-app开发,选择vue3语法,开发工具是HBliuderX。虽然内置有vuex,但是个人还是喜欢用Pinia,所以就添加进去了。 Pinia官网连接 第一步: 在项目根目录下执行命令: npm install pinia 第二步: 配置main.js文件 第三步,使用: 创建store文件夹、创建store/index.js 然后创建store/modu

    2024年02月03日
    浏览(34)
  • 如何用uni-app+vue3+vant开发微信小程序

    uni-app之前一直只支持vue2语法, 2021年8月:新版支持 了vue3 开发,App平台编译器升级为 Vite; 新版 uni-app 框架主要做了三大改进: 重写框架内核:基于 vue3 + ts 重写内置组件和API,实现更彻底、更高效的 tree-shaking ; 新增支持 Vite 构建工具,在H5平台实现秒开预览; 新增支持

    2024年02月09日
    浏览(38)
  • uni-app+vue3+vite+微信小程序开发的问题点

    目录名称不能为api,否则会出现 ├F10: PM┤ [vite] getaddrinfo ENOTFOUND rivtrust.jz-xxx.xyz ,修改为_api; vue3的全局变量挂载 或者 全局变量的引入: 或者 axios在微信小程序上使用的问题: 安装模块 出现adapter is not a function的解决方法 需要axios自定义适配器配置 整体代码request.js: un

    2024年02月13日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包