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>
相关推荐
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink4 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者6 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-6 小时前
验证码机制
前端·后端
燃先生._.7 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖8 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235248 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240259 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar9 小时前
纯前端实现更新检测
开发语言·前端·javascript