Bootstrap

uniapp在小程序连接webScoket实现余额支付

webScoket文档:uni.connectSocket(OBJECT) | uni-app官网

/plugins/event.js

const Dep = function() {
	this.Evens = Object.create(null);
}
class Event {
	constructor({
		dep = new Dep()
	} = {}) {
		if (dep.constructor === Object && Object.keys(dep).length === 0) {
			dep.Evens = Object.create(null);
		}
		this.Dep = dep;
	}
	/** 绑定事件 可以重复绑定
	 * @param {Object} handler		需要绑定的事件名称
	 * @param {Object} fn	事件处理函数
	 */
	onNotify(handler, fn, oneEv = false) {
		try{
			this.off(handler,()=>{});
		}catch(e){};
		if (typeof fn != 'function') {
			return console.error(`The registered custom event type must be a function \r\n ${fn.toString()}`);
		}
		if (this instanceof Event) {
			let typeArr = this.Dep.Evens[handler];
			if (!typeArr) {
				this.Dep.Evens[handler] = [];
			}
			const eventArr = this.Dep.Evens[handler]
			if (oneEv) {
				eventArr.splice(0, eventArr.length);
			}
			eventArr.push(fn);
		} else {
			console.error(`You can't manually modify the 'this' pointer is '${handler}' Event type \r\n ${fn.toString()}`)
		}
		return this
	}
	/** 绑定事件 仅会绑定一次事件,如果发现有重名的事件则全部移除
	 * @param {Object} handler		需要绑定的事件名称
	 * @param {Object} fn	事件处理函数
	 */
	one(handler, fn) {
		if (this instanceof Event) {
			this.on(handler, fn, true);
		} else {
			console.error(`You can't manually modify the 'this' pointer is '${handler}' Event type \r\n ${fn.toString()}`)
		}
		return this
	}
	/** 解除已经绑定事件 
	 * @param {Object} handler		指定需要解除的事件类型	不传则清楚全部
	 * @param {Object} callback		解除事件后的回调函数
	 */
	off(handler, callback) {
		if (this instanceof Event) {
			let callInfo = {
				0: {
					success: false,
					msg: `'${handler}' event is not defined`
				},
				1: {
					success: true,
					msg: 'Successful ok'
				}
			};
			if (!handler) {
				this.Dep.Evens = {};
				return true;
			}
			let typeArr = this.Dep.Evens[handler];
			if (typeArr) {
				delete this.Dep.Evens[handler];
				return callback.call(this, callInfo[1]);
			}
			return callback.call(this, callInfo[0]);
		} else {
			console.error(`You can't manually modify the 'this' pointer`)
		}
		return this
	}
	/**	触发指定事件
	 * @param {Object} type		需要触发的事件
	 * @param {Object} options	为此事件传递的参数
	 */
	onPublish(type, options) {
		if (this instanceof Event) {
			let eventArr = this.Dep.Evens[type];
			if (!eventArr || eventArr.length == 0) {
				return console.error(`The specified event does not exist is '${type}'`)
			}
			let i = eventArr.length - 1;
			while (true) {
				eventArr[i].call(this, options);
				i--
				if (i < 0) {
					break
				}
			}
		} else {
			console.error(`You can't manually modify the 'this' pointer`)
		}
		return this
	}
}
export default Event;

/utils/socket.js

import Events from '@/plugins/event';
class webScoket extends Events {
	constructor(uri) {
		super()
		this.isConnected = false //socket连接记录
		this.timer = null //心跳定时器
		this.uri = uri
		this.url = `wss://changecabinet.yunheznkj.com/websocket/${uri}`
		// 创建WebSocket连接。
		this.ws = uni.connectSocket({
			url: this.url,
			success(res) {
				console.log('链接成功')
				console.log(res)
			},
			fail(err) {
				console.log('链接失败')
				console.error(err)
			},
			complete: () => {}
		});
		// 连接打开事件
		this.ws.onOpen(res => {
			console.log(`WebSocket 已连接:${this.url}`)
			this.isConnected = true;
		});
		// 接受到服务器的消息事件
		this.ws.onMessage(res => {
			this.onPublish(this.uri, JSON.parse(res.data))
		});
		// 连接关闭事件
		this.ws.onClose(res => {
			console.warn('WebSocket 已断开')
			this.isConnected = false;
		});
	}

	close() {
		return new Promise((resolve, reject) => {
			if (this.isConnected) {
				clearInterval(this.timer);
				this.ws.close()
			}
			resolve()
		})
	}

	send(data) {
		this.ws.send({
			data: data.msg
		})
	}
}

export default webScoket

页面调用

实现逻辑:前端点击支付按钮,同时调起webScoket连接和发送支付接口。如果余额不足和支付失败,后端通过接口通知前端。如果支付成功,后端通过webScoket通知前端。

<script>
	import WS from '@/utils/socket'
	import {
		payAndGet
	} from '@/api/user.js'
	export default {
		data() {
			return {
				orderNo: '',
				$ws: null
			}
		},
		onLoad(e) {
			this.orderNo = e.orderNo
		},
		onHide() {
			if (this.$ws) {
				this.$ws.close()
			}
		},
		beforeDestroy() {
			if (this.$ws) {
				this.$ws.close()
			}
		},
		methods: {
			// 支付
			async payAndGet() {
				this.socketInit()
				const res = await payAndGet({
					orderNo: this.orderNo
				})
				if (res.code == 1001) { // 余额不足
					this.$ws.close()
				} else if (res.code == 200) { // 支付成功
				} else {// 支付失败
					this.$ws.close()
				}
			},
			// 链接设备
			socketInit() {
				let uri = `gzyh_device_result_` + this.orderNo
				this.$ws = new WS(uri)
				this.$ws.onNotify(uri, res => {
					if (res.code == 200) {
						// 支付成功执行逻辑
					}
				})
			},
		}
	}
</script>

;