1,使用方式
const ws = websocket({url: '/websocket',onmessage: e => {console.log(e)}
})
ws.close()
2,源码如下
type TimeoutHandle = ReturnType<typeof setTimeout>
interface Fn<T = any, R = T> {(...arg: T[]): R
}
interface IOptions {url: stringtoken?: stringheart_time?: numbercheck_time?: numberlock_time?: numberonmessage: Fn<any, any>onerror?: Fn<any, any>onopen?: Fn<any, any>onclose?: Fn<any, any>
}
const websocket = (options: IOptions) => {class Ws {public ws: WebSocket | undefinedprivate readonly baseUrl: string = import.meta.env.VITE_WS_BASE_API as stringprivate readonly url: string | undefinedprivate readonly onmessage: Fn<any, any>private readonly onerror?: Fn<any, any>private readonly onopen?: Fn<any, any>private readonly onclose?: Fn<any, any>private readonly token: string | undefined = tokenCookies.get()private readonly heart_time: number = 3000private readonly check_time: number = 3000private readonly lock_time: number = 4000private h_timer: TimeoutHandle | undefinedprivate c_timer: TimeoutHandle | undefinedprivate l_timer: TimeoutHandle | undefinedprivate isLock: boolean = falseconstructor(options: IOptions) {const { url, token, heart_time, check_time, lock_time } = optionsconst { onmessage, onerror, onopen, onclose } = optionsif (!url || !onmessage) {const message = !url ? '链接url' : '回调函数onmessage'throw new Error(`socket${message}不能为空`)}this.url = this.baseUrl + urlthis.onmessage = onmessageif (!!onerror) {this.onerror = onerror}if (!!onopen) {this.onopen = onopen}if (!!onclose) {this.onclose = onclose}this.token = token || tokenCookies.get()this.heart_time = heart_time || 3000this.check_time = check_time || 3000this.lock_time = lock_time || 4000this.wsInit()}public wsInit(): void {if (!this.url || !this.token) {return}const url = this.url + '?token=' + this.tokenconst 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 = truethis.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 {;(this.ws as WebSocket).close()this.clearTimeout()}}return new Ws(options)
}
export default websocket