/
websocketbridge.ts
66 lines (60 loc) · 2.01 KB
/
websocketbridge.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { JDBridge } from "../bridge"
import { CLOSE } from "../constants"
export class WebSocketBridge extends JDBridge {
private _ws: WebSocket
private _startPromise: Promise<void>
constructor(
name: string,
readonly url: string,
readonly protocols?: string | string[]
) {
super(name, true)
this.mount(() => this.close())
}
private close() {
console.debug(`web bridge closed`, { url: this.url })
const opened = !!this._ws || !!this._startPromise
try {
this._ws?.close()
this._ws = undefined
this._startPromise = undefined
} catch (e) {
console.warn(e)
}
if (opened) this.emit(CLOSE)
}
async connect() {
if (this._ws) return Promise.resolve()
if (!this._startPromise) {
this._startPromise = new Promise<void>((resolve, reject) => {
const ws = new WebSocket(this.url, this.protocols)
ws.binaryType = "arraybuffer"
ws.onopen = () => {
this._ws = ws
this._startPromise = undefined
console.debug(`web bridge opened`, { url: this.url })
resolve()
}
ws.onerror = e => {
console.debug(`web bridge error`, { url: this.url })
this.close()
reject()
}
ws.onclose = ev => {
console.debug(`web bridge onclose`, { ev })
this.close()
}
ws.onmessage = (ev: MessageEvent<ArrayBuffer>) => {
const { data } = ev
const buffer = new Uint8Array(data)
this.receiveFrameOrPacket(buffer)
}
})
}
return this._startPromise
}
protected sendPacket(data: Uint8Array, sender: string): void {
this.connect()
this._ws?.send(data)
}
}