uniapp封装websocket文件(app、h5兼容)

适合场景:只需要发送一次数据,服务器可以实时返回数据进行渲染。

socket文件

javascript 复制代码
let isSocketClose = false; // 是否关闭socket
let reconnectCount = 5; // 重连次数
// let heartbeatInterval = ""; // 心跳定时器
let socketTask = null; // websocket对象

let againTimer = null; //断线重连定时器


let url = null;
let onReFn = null;
let onSucFn = null;
let onErrFn = null;

/**
 * sockeUrl:websocet的地址
 * onReceive:消息监听的回调
 * onErrorEvent:抛出错误的回调,且弹窗连接失败的提示框
 * onErrorSucceed:抛出成功回调,主要用于隐藏连接失败的提示框
 * */
const sokcet = (sockeUrl, onReceive, onErrorEvent, onErrorSucceed) => {
	url = sockeUrl;
	onReFn = onReceive;
	onErrFn = onErrorEvent;
	onSucFn = onErrorSucceed;
	isSocketClose = false;
	//判断是否有websocet对象,有的话清空
	if (socketTask) {
		console.log('清空ws');
		socketTask.close();
		socketTask = null;
		// clearInterval(heartbeatInterval);
	}

	//WebSocket的地址
	// 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】
	let url = sockeUrl
	// 连接
	socketTask = uni.connectSocket({
		url: url,
		success(data) {
			console.log('清空ws重连定时器');
			clearInterval(againTimer) //断线重连定时器
			console.log("连接成功!");
		},
		fail: (err) => {
			console.log(url)
			console.log("报错", err);
		}
	});

	// 连接打开
	socketTask.onOpen((res) => {
		console.log('WebSocket打开');
		uni.showToast({
			title: 'loading...',
			icon: 'none',
		})
		clearInterval(againTimer) //断线重连定时器
		onErrorSucceed({
			isShow: false
		}) // 用于提示框的隐藏
		// heartbeatInterval && clearInterval(heartbeatInterval);
		// 10秒发送一次心跳
		// heartbeatInterval = setInterval(() => {
		// 	sendMsg('心跳ing')
		// }, 1000 * 5)
	})
	// 监听连接失败
	socketTask.onError((err) => {
		console.log('WebSocket连接打开失败,请检查', err);
		//停止发送心跳
		// clearInterval(heartbeatInterval)
		//如果不是人为关闭的话,进行重连
		if (!isSocketClose) {
			reconnect(url, onErrorEvent)
		}
	})

	// // 监听连接关闭 -
	socketTask.onClose((e) => {
		console.log('WebSocket连接关闭!');
		// clearInterval(heartbeatInterval)
		console.log(isSocketClose, 123);
		if (!isSocketClose) {
			reconnect(url, onErrorEvent)
		}
	})

	// 监听收到信息
	socketTask.onMessage((res) => {
		uni.hideLoading()
		// console.log(res, 'res监听收到信息')
		let serverData = res.data
		//与后端规定好返回值分别代表什么,写业务逻辑
		serverData && onReceive(serverData);
	});
}

const reconnect = (url, onErrorEvent) => {
	console.log('进入断线重连1', isSocketClose);

	clearInterval(againTimer) //断线重连定时器
	// clearInterval(heartbeatInterval);
	socketTask && socketTask.close(); // 确保已经关闭后再重新打开
	console.log('进入断线重连2', isSocketClose);
	socketTask = null;
	onErrorEvent({
		isShow: true,
		messge: '扫描头服务正在连接...'
	})
	uni.showToast({
		title: 'loading...',
		icon: 'none',
	})
	// 连接  重新调用创建websocet方法
	againTimer = setInterval(() => {
		sokcet(url, onReFn, onErrFn, onSucFn)
		console.log('在重新连接中...');

	}, 1000)


}

const sendMsg = (msg) => { //向后端发送命令
	msg = JSON.stringify(msg)
	try {
		//通过 WebSocket 连接发送数据
		socketTask.send({
			data: msg
		});
	} catch (e) {
		console.log(e, "sendMsg Error");
		if (isSocketClose) {
			return
		} else {
			reconnect(url, onErrFn)
		}

	}
}
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}

const stop = () => {
	console.log("关闭定时器1");
	isSocketClose = true
	// clearInterval(heartbeatInterval);
	clearInterval(againTimer) //断线重连定时器
	socketTask.close(); // 确保已经关闭后再重新打开
	socketTask = null;
	console.log("关闭定时器2", socketTask);
}


const $debounce = function(fn, wait) {
	let timer = null;
	return function() {
		if (timer !== null) {
			clearTimeout(timer);
		}
		timer = setTimeout(fn, wait);
	}
}


export const websocetObj = {
	sokcet,
	stop,
	sendMsg
};

页面中使用

javascript 复制代码
	<script>
	import {
		websocetObj
	} from '@/common/websocket.js';
	export default {
		methods:{
				//websocet函数回调:返回监听的数据
			getWebsocetData(val) {
				this.bids = JSON.parse(val).data.tick.bids
				this.asks = JSON.parse(val).data.tick.asks
			},
			//websocet函数抛错: 返回错误信息 用于用户提示
			getWebsocetError(err) {
				this.socketShow = err.isShow;
				this.webtext = err.messge;
				console.log('websocet函数抛错', this.socketShow);
			},
			//websocet函数成功进入: 监听连接状态,在失败的时候弹窗提示,具体需求看自身情况
			onErrorSucceed(val) {
				this.socketShow = val.isShow;
				websocetObj.sendMsg({
					"api": "market_depth",
					"symbol": this.currencyShortParam
				})
			},
			websocket() {
				websocetObj.sokcet('ws://18.166.64.181:2346', this.getWebsocetData, this.getWebsocetError, this
					.onErrorSucceed) //请求地址
			},
			stopSocket() {
				websocetObj.stop()
			}
		},
		onShow() {
			this.websocket()
		},
		onHide() {
			this.stopSocket()
		},
	}
	</script>
相关推荐
丷丩7 小时前
MapLibre GL JS第20课:更新GeoJSON多边形
前端·javascript·gis·mapbox·maplibre gl js
swipe7 小时前
DeepAgents middleware 工程实战:把复杂 Agent 的运行时基建交给可组合中间件
前端·面试·llm
前端环境观察室7 小时前
别让 Agent 浏览器任务无限重试:失败分类、RetryPolicy 与人工复核
前端
喵个咪7 小时前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
前端·vue.js·react.js
m0_738120727 小时前
渗透测试基础——黑盒测试下的Web漏洞挖掘与利用解析(一)
服务器·前端·网络·安全·php
Larcher9 小时前
JS 变量提升:代码没动,为什么执行顺序就变了?
前端·javascript·前端框架
yingyima9 小时前
MySQL 事件调度器速查:核心语法与实战代码
前端
GISer_Jing9 小时前
Claude Code多Agent架构深度剖析
前端·人工智能·架构·自动化
comphub9 小时前
comp-hub:让你的 Vue 业务组件真正"活"起来
前端
AI砖家9 小时前
Claude Code 跳过确认完全指南:让 AI 自己完成开发任务
前端·人工智能·python·ai编程·代码规范