ts + websocket封装

发布时间:2024年01月23日

1,使用方式

// 开始链接websocket
const ws = websocket({
    url: '/websocket',
    onmessage: e => {
        // 获取websocket信息
        console.log(e)
    }
})

// 关闭websocket
ws.close()

2,源码如下

// 定义定时器
type TimeoutHandle = ReturnType<typeof setTimeout>

// 定义回调函数
interface Fn<T = any, R = T> {
    (...arg: T[]): R
}

// 定义参数
interface IOptions {
	// 链接
	url: string
	// token
	token?: string
	// 发送心跳间隔时间
	heart_time?: number
	//检查链接状态时间
	check_time?: number
	//断线后重连间隔时间
	lock_time?: number
	// 成功回调
	onmessage: Fn<any, any>
	// 失败回调
	onerror?: Fn<any, any>
	// 打开回调
	onopen?: Fn<any, any>
	// 关闭回调
	onclose?: Fn<any, any>
}

// 方法
const websocket = (options: IOptions) => {
	class Ws {
		// socket实例
		public ws: WebSocket | undefined
		// 默认基础地址
		private readonly baseUrl: string = import.meta.env.VITE_WS_BASE_API as string
		// socket 地址
		private readonly url: string | undefined
		// socket请求成功数据返回回调函数
		private readonly onmessage: Fn<any, any>
		// socket请求失败返回回调函数
		private readonly onerror?: Fn<any, any>
		// socket打开回调
		private readonly onopen?: Fn<any, any>
		// socket关闭回调
		private readonly onclose?: Fn<any, any>
		// token
		private readonly token: string | undefined = tokenCookies.get()
		// 心跳时间
		private readonly heart_time: number = 3000
		// 检查链接状态时间
		private readonly check_time: number = 3000
		// 重连时间
		private readonly lock_time: number = 4000
		// 心跳定时器
		private h_timer: TimeoutHandle | undefined
		// 检查链接定时器
		private c_timer: TimeoutHandle | undefined
		// 重连定时器
		private l_timer: TimeoutHandle | undefined
		// 重连锁
		private isLock: boolean = false

		constructor(options: IOptions) {
			const { url, token, heart_time, check_time, lock_time } = options
			const { onmessage, onerror, onopen, onclose } = options
			if (!url || !onmessage) {
				const message = !url ? '链接url' : '回调函数onmessage'
				throw new Error(`socket${message}不能为空`)
			}

			// 链接url
			this.url = this.baseUrl + url
			// 数据返回回调函数
			this.onmessage = onmessage
			// 失败回调
			if (!!onerror) {
				this.onerror = onerror
			}
			// 打开回调
			if (!!onopen) {
				this.onopen = onopen
			}
			// 关闭回调
			if (!!onclose) {
				this.onclose = onclose
			}
			// token
			this.token = token || tokenCookies.get()
			// 心跳时间
			this.heart_time = heart_time || 3000
			// 检查链接状态时间
			this.check_time = check_time || 3000
			// 重连时间
			this.lock_time = lock_time || 4000

			// 初始化
			this.wsInit()
		}

		// 初始化socket
		public wsInit(): void {
			if (!this.url || !this.token) {
				return
			}
			// 拼接token
			const url = this.url + '?token=' + this.token
			const ws = new WebSocket(url)

			// 打开处理
			ws.onopen = e => {
				// 心跳
				this.heartCheck()
				// 打开回调
				if (!!this.onopen) {
					this.onopen(e)
				}
			}

			// 错误处理
			ws.onclose = e => {
				// 重连
				if (!!this.token) {
					this.reconnect()
				}
				// 关闭回调
				if (!!this.onclose) {
					this.onclose(e)
				}
			}

			// 错误处理
			ws.onerror = e => {
				// 重连
				if (!!this.token) {
					this.reconnect()
				}
				// 回调
				if (!!this.onerror) {
					this.onerror(e)
				}
			}

			// 消息接收
			ws.onmessage = e => {
				// 心跳
				this.heartCheck()
				// 回调
				this.onmessage(e)
			}

			// 赋值
			this.ws = ws
		}

		// 心跳
		private heartCheck(): void {
			// 清除心跳、检查链接定时器
			this.clearTimeout()
			// 心跳定时器
			this.h_timer = setTimeout(() => {
				;(this.ws as WebSocket).send('type:ping')
				// 检查链接定时器
				this.c_timer = setTimeout(() => {
					// 连接失败,进行关闭
					if ((this.ws as WebSocket).readyState !== 1) {
						this.close()
					}
				}, this.check_time)
			}, this.heart_time)
		}

		// 重连
		private reconnect(): void {
			if (this.isLock) {
				return
			}

			this.isLock = true
			this.l_timer && clearTimeout(this.l_timer)
			// 重连定时器
			this.l_timer = setTimeout(() => {
				this.wsInit()
				this.isLock = false
			}, this.lock_time)
		}

		// 清除心跳、检查链接定时器
		private clearTimeout(): void {
			this.h_timer && clearTimeout(this.h_timer)
			this.c_timer && clearTimeout(this.c_timer)
		}

		// 销毁关闭
		public close(): void {
			// 关闭WebSocket
			;(this.ws as WebSocket).close()
			// 清除心跳、检查链接定时器
			this.clearTimeout()
		}
	}

	return new Ws(options)
}
export default websocket

文章来源:https://blog.csdn.net/mf_717714/article/details/135769773
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。