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>
相关推荐
雾岛听风来几秒前
Android开发中常用高效数据结构
前端·javascript·后端
IT_陈寒几秒前
Vue 3性能优化实战:这5个Composition API技巧让你的应用快30%
前端·人工智能·后端
IT_陈寒8 分钟前
Vue3性能翻倍的5个秘密:从Composition API到Tree Shaking实战指南
前端·人工智能·后端
2501_9160074713 分钟前
Fastlane 结合 开心上架 命令行版本实现跨平台上传发布 iOS App
android·ios·小程序·https·uni-app·iphone·webview
IT_陈寒22 分钟前
JavaScript 性能优化:3个V8引擎隐藏技巧让你的代码提速50%
前端·人工智能·后端
iOS阿玮25 分钟前
请及时同意苹果开发者协议,避免影响迭代工作。
uni-app·app·apple
沐怡旸37 分钟前
【技术选型】前端框架:Vue vs React - 组合式API与Hooks的哲学之争
前端·面试
charlie1145141911 小时前
HTML 理论系统笔记2
前端·笔记·学习·html·基础·1024程序员节·原生
2501_938780281 小时前
Ionic + Angular 跨端实战:用 Capacitor 实现相机拍照功能并适配移动端
前端·数码相机·angular.js
00后程序员张1 小时前
iOS 26 内存占用监控 多工具协同下的性能稳定性分析实战
android·macos·ios·小程序·uni-app·cocoa·iphone