-
Notifications
You must be signed in to change notification settings - Fork 5
/
RoutedWebSocket.ts
126 lines (107 loc) · 4.34 KB
/
RoutedWebSocket.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import {computedFrom} from "../computedFrom";
import IHydratedWebSocketEventMap from "../IHydratedWebSocketEventMap";
import CloseEvent from "../polyfill/CloseEvent";
import Event from "../polyfill/Event";
import WebSocket from "../polyfill/WebSocket";
import {Shell} from "../Shell";
export class RoutedWebSocket extends Shell {
public set onmessage(f: (ev: MessageEvent) => any) {
super.setOnmessage(f);
this.checkSubscriptions();
}
public get onmessage(): (ev: MessageEvent) => any {
return super.getOnmessage();
}
public get url(): string {
return "";
}
public get bufferedAmount(): number {
return 0;
}
public get extensions(): string {
return "";
}
public get protocol(): string {
return "";
}
/** The connection is not yet open. */
public readonly CONNECTING = WebSocket.CONNECTING;
/** The connection is open and ready to communicate. */
public readonly OPEN = WebSocket.OPEN;
/** The connection is in the process of closing. */
public readonly CLOSING = WebSocket.CLOSING;
/** The connection is closed or couldn't be opened. */
public readonly CLOSED = WebSocket.CLOSED;
private virtualReadyState: number = null;
private subscribed: boolean = false;
constructor(
private readonly routerSend: (data: string | ArrayBuffer | Blob | ArrayBufferView) => void,
private readonly routerClose: (code: number, reason: string) => void,
private readonly onMessageSubscribe?: (ws: RoutedWebSocket) => void,
private readonly onMessageUnsubscribe?: (ws: RoutedWebSocket) => void,
) {
super();
}
public setReadyState(state: number) {
if (this.virtualReadyState === state) {
return;
}
this.virtualReadyState = state;
switch (state) {
case this.OPEN:
this.dispatchEvent(new Event("open"));
break;
case this.CLOSED:
this.dispatchEvent(new CloseEvent("close"));
break;
default:
break;
}
}
public addEventListener<K extends keyof IHydratedWebSocketEventMap>(type: K,
listener: (this: WebSocket,
ev: IHydratedWebSocketEventMap[K])
=> any,
useCapture?: boolean): void {
super.addEventListener(type, listener, useCapture);
this.checkSubscriptions();
}
public removeEventListener<K extends keyof IHydratedWebSocketEventMap>(type: K,
listener: (this: WebSocket,
ev: IHydratedWebSocketEventMap[K])
=> any,
useCapture?: boolean): void {
super.removeEventListener(type, listener, useCapture);
this.checkSubscriptions();
}
public emitMessage(event: MessageEvent) {
this.dispatchEvent(event);
}
public send(data: string | ArrayBuffer | Blob | ArrayBufferView): void {
this.routerSend(data);
}
public close(code: number = 1000, reason?: string) {
this.virtualReadyState = this.CLOSED;
this.routerClose(code, reason);
}
protected getReadyState(): number {
return this.virtualReadyState === null ? WebSocket.CONNECTING : this.virtualReadyState;
}
private checkSubscriptions() {
if (this.onmessage || (this.listeners.has("message") && this.listeners.get("message").length)) {
if (!this.subscribed) {
this.subscribed = true;
if (this.onMessageSubscribe) {
this.onMessageSubscribe(this);
}
}
} else {
if (this.subscribed) {
this.subscribed = false;
if (this.onMessageUnsubscribe) {
this.onMessageUnsubscribe(this);
}
}
}
}
}