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>
相关推荐
我要洋人死43 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#