webscoket之结合pinia 全局状态版本

创作灵感 有一天我接到一个小小需求做手机小程序 和机顶盒大屏端的语音ai助手的消息同步
当时就选了 万恶的websocket  但是它需要挂在全局  我做了语音接受发送模块  页面模块 消息记录模块 以及消息展示模块 和 ai垂类模型切换模块 
分了四大模块  我都有连接使用websocket 那显然 我直接在局部组件去使用new webscoket这个玩意肯定是很不合理的 为了方便本懒狗偷懒 我果断用了一手pinia 和 webscoket结合拉这样 我只用在最外面的破组件里面去init 全局都可以使用这个websocket拉

下面 看破代码

export const useWebsocketStore = defineStore('useWebsocketStore', {
	state: () => ({
		url: "wss://*****:****/chatStream/stream/ws/sync?",
		ws: null,
		reconnect_current: 0,
		reconnect_count: 3,
		reconnect_timer: null,
		reconnect_interval: 3000,
		is_reonnect: false,
		socket_open: false,
		hearbeat_timer: null,
		hearbeat_interval: 5000,
	}),
	actions: {
		initWebSocket(authorization, group_id, onMessage) {
			if (this.ws) {
				return this.ws
			}
			console.log("你老米")

			this.ws = uni.connectSocket({
				url: this.url + "authorization=" + authorization + "&group_id=" + group_id, //接口地址。
				success: (e) => {
					console.log('连接成功', e);
					// 返回实例
				}
			})

			this.ws.onOpen((e) => {
				console.log(
					"webSocket open 连接成功",
					e,
					this.ws
				);

				if (this.reconnect_current == 0) {
					let data = {
						kind: 1, //请求类型 kind 1 首次连接开启
						kindString: "socketStart",
					};

					this.sendMsg(data);
				}

				clearTimeout(this.reconnect_timer);

				this.reconnect_current = 0;
				this.socket_open = true;
				this.is_reonnect = true;
				this.heartbeat();
			});

			this.ws.onClose((e) => {
				console.log(
					"webSocket close 连接已断开",
					e,
					this.reconnect_current
				);
				clearInterval(this.hearbeat_timer);
				this.socket_open = false;
				// 断开重连的处理 查看是否主动断开 来进行重连
				if (this.is_reonnect) {
					// 确立this 指向
					let _this = this;

					this.reconnect_timer = setTimeout(() => {
						// 超过重连次数
						if (_this.reconnect_current > _this.reconnect_count) {
							clearTimeout(_this.reconnect_timer);
							// 释放对象
							_this.ws = null;
							return;
						}
						// 记录重连次数
						_this.reconnect_current++;

						_this.reconnect();
					}, this.reconnect_interval);
				}
			});

			this.ws.onError(() => {
				// console,log("....error")
			});
			this.ws.onMessage((e) => {
				var params = JSON.parse(e.data);
				console.log("webSocket message", params);

				this.messageReceive(params, onMessage);

			});
		},

		messageReceive(e, onMessage) {
			onMessage(e);
		},
		// 发送消息
		sendMsg(data, callback = null) {
			//已开启
			// console.log("执行发送", data, this.ws);
			if (this.ws.readyState == this.ws.OPEN) {

				this.ws.send({
					data: JSON.stringify(data),
					success: (e) => {
						console.log("发送成功==?》", e)
					}
				});

				if (callback) {
					callback();
				}

			}
		},
		heartbeat() {
			if (this.hearbeat_timer) {
				clearInterval(this.hearbeat_timer);
			}

			let _this = this;

			this.hearbeat_timer = setInterval(() => {
				var data = {
					kind: 0, //请求类型 kind 0 心跳包
					kindString: "heartBeat",
				};
				//   console.log("里面==》", _this, JSON.stringify(data));
				_this.sendMsg(data);
			}, this.hearbeat_interval);
		},
		reconnect() {
			if (this.ws && this.socket_open) {
				this.ws.close();
			}

			this.ws = null;
			// console.log("执行重连===>", this);
			this.initWebSocket();
		},
		destory() {
			if (this.ws != null && this.ws.readyState == this.ws.OPEN) {
				console.log("释放对象===》不进行联动")
				clearInterval(this.hearbeat_interval);
				this.is_reonnect = false;
				this.ws.close();

			}
			// 释放对象
			this.ws = null;
		}

	}
});

当然和传统web端的变化区别只在那啥 怎么说来着 api 上面

出示一下使用代码 嘿嘿
 

	import {
		useWebsocketStore
	} from "@/store/infomation";


    const useWebsocket = useWebsocketStore();

    import {
		storeToRefs
	} from "pinia"
   
    const {
		ws
	} = storeToRefs(useWebsocket)
    
    // 多的不说初始化
    useWebsocket.initWebSocket(token.value, IpTVInfo.value.group_id, onMessage)
   
    // 这个用来接收处理消息 其他我就不多写啦宝贝们
    const onMessage = (e) => {
		console.log("前端接收socket消息===>", e, ws.value)


		if (e.type == "group_info") {
			if (e.data.master_number !== userInfo.value.phone) {
				console.log("机顶盒账号与手机账号不符");
				// useWebsocket.destory();
				return;
			};

			IpTVInfo.value = {
				type: 2, // 1是添加 2连接
				telPhone: e.data.master_number,
				group_id: e.data.group_id,
				chat_id: e.data.chat_id,
				app_id: e.data.app_id,
				member_id: e.data.member_id,
			};

			checkId.value = IpTVInfo.value.app_id;
			chatId.value = IpTVInfo.value.chat_id;
			uni.showToast({
				title: `连接成功`,
				icon: 'none'
			})


			console.log("前端接收socket消息后===>", checkId.value, chatId.value, 
       IpTVInfo.value)

			// infomationStore.resetIptvInfo()
		}

		if (e.type === "broadcast") {
			console.log("前端接收socket切换消息===>", e);
			IpTVInfo.value.chat_id = e.data.chatId;
			IpTVInfo.value.group_id = e.data.groupId;
			IpTVInfo.value.app_id = e.data.appId;
			IpTVInfo.value.member_id = e.data.memberId;

			historyList.value = [];
			historytime.value = "";
			// shouTop.value = false
			isUphistory.value = false;
			checkId.value = IpTVInfo.value.app_id;
			chatId.value = IpTVInfo.value.chat_id;
			updateIndex.value++
		}
	};

    //某块发送展示一下
      
      let data = {
					type: 'broadcast',
					data: {
						type: 'switchApplication',
						chatId: chatId.value,
						groupId: IpTVInfo.value.group_id,
						appId: checkId.value,
						memberId: userInfo.value.member_id
					}
				};

	useWebsocket.sendMsg(data);

    

本资源为黑龙江省 2023 年水系分布数据,涵盖河流、沟渠、支流等线状要素,以及湖泊、水库、湿地等面状水体,提供完整的二维水文地理框架。数据以标准 GIS 格式发布,包含可编辑 MXD 工程文件、Shapefile 数据以及标准制图 TIF,适用于科研、规划设计、生态评估与地图制图等多类应用场景。 【数据内容】 1、水系线状要素(.shp) 包括主要河流、支流、人工渠道等 属性字段涵盖:名称、类别等 线要素拓扑规范,无断裂与悬挂节点 2、水体面状要素(.shp) 覆盖湖泊、水库、池塘、湿地等面状水体 属性包含:名称、类型等信息 几何边界经过平滑与精修,保证面积统计可靠 3、可编辑 MXD 工程文件(.mxd) 预设图层渲染、图例、比例尺、指北针与布局 支持用户根据自身制图需求快速调整样式、色带及标注规则 博主使用的 ArcMap 10.8 环境 4、标准成图 TIF(.tif) 专业级地图输出,含必要图廓与标注,可直接用于报告、论文与展示 输出分辨率高,适合印刷与电子稿应用 【数据技术说明】 坐标系统:WGS 84 地理坐标系 数据年份:2023 年 制作流程:基于卫星影像、水利普查数据和地理编码信息进行提取 → 几何校正 → 拓扑审查 → 分类整理 → 成图渲染 质量控制措施:保证线状与面状水体不重叠、不缺失;对水库与湖泊边界进行了人工校核,提高空间精度 【应用价值】 地表水资源调查与监测,水利、水文模型的空间输入,城市与农村规划中的水系布局分析,生态修复、水环境治理与湿地保护研究,教学、制图与地理信息可视化应用 【使用说明】 首次打开 MXD 文件前,请确保 Shapefile 和栅格文件均已解压至同一目录,以免出现路径丢失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值