@orderly.network/net 1.0.32 → 1.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +12 -0
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +156 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +156 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/ws/ws.ts +198 -32
package/src/ws/ws.ts
CHANGED
|
@@ -39,6 +39,9 @@ type Topics = {
|
|
|
39
39
|
const defaultMessageFormatter = (message: any) => message.data;
|
|
40
40
|
const COMMON_ID = "OqdphuyCtYWxwzhxyLLjOWNdFP7sQt8RPWzmb5xY";
|
|
41
41
|
|
|
42
|
+
const TIME_OUT = 1000 * 60 * 2;
|
|
43
|
+
const CONNECT_LIMIT = 5;
|
|
44
|
+
|
|
42
45
|
export class WS {
|
|
43
46
|
private publicSocket!: WebSocket;
|
|
44
47
|
private privateSocket?: WebSocket;
|
|
@@ -57,6 +60,12 @@ export class WS {
|
|
|
57
60
|
private _eventHandlers: Map<string, Topics> = new Map();
|
|
58
61
|
private _eventPrivateHandlers: Map<string, Topics> = new Map();
|
|
59
62
|
|
|
63
|
+
private _publicHeartbeatTime?: number;
|
|
64
|
+
private _privateHeartbeatTime?: number;
|
|
65
|
+
|
|
66
|
+
private _publicRetryCount: number = 0;
|
|
67
|
+
private _privateRetryCount: number = 0;
|
|
68
|
+
|
|
60
69
|
constructor(private options: WSOptions) {
|
|
61
70
|
this.createPublicSC(options);
|
|
62
71
|
|
|
@@ -69,23 +78,93 @@ export class WS {
|
|
|
69
78
|
|
|
70
79
|
private bindEvents() {
|
|
71
80
|
if (typeof document !== "undefined") {
|
|
72
|
-
document.addEventListener(
|
|
81
|
+
document.addEventListener(
|
|
82
|
+
"visibilitychange",
|
|
83
|
+
this.onVisibilityChange.bind(this)
|
|
84
|
+
);
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
if (typeof window !== "undefined") {
|
|
76
|
-
window.addEventListener("online", this.onNetworkStatusChange);
|
|
77
|
-
window.addEventListener("offline", this.onNetworkStatusChange);
|
|
88
|
+
window.addEventListener("online", this.onNetworkStatusChange.bind(this));
|
|
89
|
+
// window.addEventListener("offline", this.onNetworkStatusChange);
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
|
|
81
93
|
private onVisibilityChange() {
|
|
82
94
|
console.log("👀👀 document visibility 👀👀", document.visibilityState);
|
|
83
|
-
if (document.visibilityState) {
|
|
95
|
+
if (document.visibilityState === "visible") {
|
|
96
|
+
this.checkSocketStatus();
|
|
84
97
|
}
|
|
98
|
+
// else {
|
|
99
|
+
// this.publicSocket.close();
|
|
100
|
+
// this.privateSocket?.close();
|
|
101
|
+
// }
|
|
85
102
|
}
|
|
86
103
|
|
|
87
104
|
private onNetworkStatusChange() {
|
|
88
105
|
console.log("👀👀 network status 👀👀", navigator.onLine);
|
|
106
|
+
|
|
107
|
+
if (navigator.onLine) {
|
|
108
|
+
this.checkSocketStatus();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 判断当前连接状态,
|
|
114
|
+
* 1、如果已断开则重连
|
|
115
|
+
* 2、如果太久没有收到消息,则主动断开,并重连
|
|
116
|
+
* 3、从后台返回、网络状态变化时,都走以下流程
|
|
117
|
+
*/
|
|
118
|
+
private checkSocketStatus() {
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
|
|
121
|
+
console.log(
|
|
122
|
+
"👀👀 checkNetworkStatus 👀👀",
|
|
123
|
+
this._publicHeartbeatTime,
|
|
124
|
+
this._privateHeartbeatTime,
|
|
125
|
+
now,
|
|
126
|
+
this.publicSocket.readyState,
|
|
127
|
+
this.privateSocket?.readyState
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// check the last time
|
|
131
|
+
// 如果容器不可见,则不做处理
|
|
132
|
+
if (document.visibilityState !== "visible") return;
|
|
133
|
+
// 如果网络不可用,则不做处理
|
|
134
|
+
if (!navigator.onLine) return;
|
|
135
|
+
|
|
136
|
+
// 如果已断开,则重连
|
|
137
|
+
// public
|
|
138
|
+
if (!this.publicIsReconnecting) {
|
|
139
|
+
if (this.publicSocket.readyState === WebSocket.CLOSED) {
|
|
140
|
+
this.reconnectPublic();
|
|
141
|
+
} else {
|
|
142
|
+
console.log(
|
|
143
|
+
"***********************",
|
|
144
|
+
this.publicSocket.readyState,
|
|
145
|
+
now - this._publicHeartbeatTime!
|
|
146
|
+
);
|
|
147
|
+
if (now - this._publicHeartbeatTime! > TIME_OUT) {
|
|
148
|
+
//unsubscribe all public topic
|
|
149
|
+
this.publicSocket.close();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!this.privateIsReconnecting) {
|
|
155
|
+
// private
|
|
156
|
+
if (this.privateSocket?.readyState === WebSocket.CLOSED) {
|
|
157
|
+
this.reconnectPrivate();
|
|
158
|
+
} else {
|
|
159
|
+
if (
|
|
160
|
+
this._privateHeartbeatTime &&
|
|
161
|
+
now - this._privateHeartbeatTime! > TIME_OUT
|
|
162
|
+
) {
|
|
163
|
+
// unsubscribe all private topic
|
|
164
|
+
this.privateSocket?.close();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
89
168
|
}
|
|
90
169
|
|
|
91
170
|
public openPrivate(accountId: string) {
|
|
@@ -108,17 +187,22 @@ export class WS {
|
|
|
108
187
|
}
|
|
109
188
|
|
|
110
189
|
private createPublicSC(options: WSOptions) {
|
|
190
|
+
console.log("open public webSocket ---->>>>");
|
|
191
|
+
if (this.publicSocket && this.publicSocket.readyState === WebSocket.OPEN)
|
|
192
|
+
return;
|
|
111
193
|
this.publicSocket = new WebSocket(
|
|
112
194
|
`${this.options.publicUrl}/ws/stream/${COMMON_ID}`
|
|
113
195
|
);
|
|
114
196
|
this.publicSocket.onopen = this.onOpen.bind(this);
|
|
115
197
|
this.publicSocket.onmessage = this.onPublicMessage.bind(this);
|
|
116
|
-
this.publicSocket.onclose = this.
|
|
117
|
-
this.publicSocket.onerror = this.
|
|
198
|
+
this.publicSocket.onclose = this.onPublicClose.bind(this);
|
|
199
|
+
this.publicSocket.onerror = this.onPublicError.bind(this);
|
|
118
200
|
}
|
|
119
201
|
|
|
120
202
|
private createPrivateSC(options: WSOptions) {
|
|
121
|
-
console.log("
|
|
203
|
+
console.log("open private webSocket ---->>>>");
|
|
204
|
+
if (this.privateSocket && this.privateSocket.readyState === WebSocket.OPEN)
|
|
205
|
+
return;
|
|
122
206
|
|
|
123
207
|
this.options = options;
|
|
124
208
|
|
|
@@ -127,12 +211,13 @@ export class WS {
|
|
|
127
211
|
);
|
|
128
212
|
this.privateSocket.onopen = this.onPrivateOpen.bind(this);
|
|
129
213
|
this.privateSocket.onmessage = this.onPrivateMessage.bind(this);
|
|
130
|
-
|
|
214
|
+
this.privateSocket.onclose = this.onPrivateClose.bind(this);
|
|
131
215
|
this.privateSocket.onerror = this.onPrivateError.bind(this);
|
|
132
216
|
}
|
|
133
217
|
|
|
134
218
|
private onOpen(event: Event) {
|
|
135
|
-
console.log("WebSocket connection opened
|
|
219
|
+
console.log("Public WebSocket connection opened");
|
|
220
|
+
|
|
136
221
|
// console.log(this._pendingPublicSubscribe);
|
|
137
222
|
if (this._pendingPublicSubscribe.length > 0) {
|
|
138
223
|
this._pendingPublicSubscribe.forEach(([params, cb, isOnce]) => {
|
|
@@ -142,13 +227,15 @@ export class WS {
|
|
|
142
227
|
}
|
|
143
228
|
|
|
144
229
|
this.publicIsReconnecting = false;
|
|
230
|
+
this._publicRetryCount = 0;
|
|
145
231
|
}
|
|
146
232
|
|
|
147
233
|
private onPrivateOpen(event: Event) {
|
|
148
|
-
console.log("Private WebSocket connection opened
|
|
234
|
+
console.log("Private WebSocket connection opened");
|
|
149
235
|
//auth
|
|
150
236
|
this.authenticate(this.options.accountId!);
|
|
151
237
|
this.privateIsReconnecting = false;
|
|
238
|
+
this._privateRetryCount = 0;
|
|
152
239
|
}
|
|
153
240
|
|
|
154
241
|
private onMessage(
|
|
@@ -184,11 +271,13 @@ export class WS {
|
|
|
184
271
|
}
|
|
185
272
|
});
|
|
186
273
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
274
|
+
// 延时删除,在重连时还需要用到
|
|
275
|
+
// if (eventhandler.isOnce) {
|
|
276
|
+
// handlerMap.delete(topicKey);
|
|
277
|
+
// }
|
|
190
278
|
}
|
|
191
279
|
}
|
|
280
|
+
|
|
192
281
|
// console.log("WebSocket message received:", message);
|
|
193
282
|
} catch (e) {
|
|
194
283
|
console.log("WebSocket message received:", e, event.data);
|
|
@@ -199,10 +288,14 @@ export class WS {
|
|
|
199
288
|
|
|
200
289
|
private onPublicMessage(event: MessageEvent) {
|
|
201
290
|
this.onMessage(event, this.publicSocket, this._eventHandlers);
|
|
291
|
+
// 更新最后收到消息的时间
|
|
292
|
+
this._publicHeartbeatTime = Date.now();
|
|
202
293
|
}
|
|
203
294
|
|
|
204
295
|
private onPrivateMessage(event: MessageEvent) {
|
|
205
296
|
this.onMessage(event, this.privateSocket!, this._eventPrivateHandlers);
|
|
297
|
+
// 更新最后收到消息的时间
|
|
298
|
+
this._privateHeartbeatTime = Date.now();
|
|
206
299
|
}
|
|
207
300
|
|
|
208
301
|
private handlePendingPrivateTopic() {
|
|
@@ -214,31 +307,83 @@ export class WS {
|
|
|
214
307
|
}
|
|
215
308
|
}
|
|
216
309
|
|
|
217
|
-
private
|
|
218
|
-
console.log("
|
|
310
|
+
private onPublicClose(event: CloseEvent) {
|
|
311
|
+
console.log("public socket is closed");
|
|
312
|
+
|
|
313
|
+
// move handler to pending
|
|
314
|
+
this._eventHandlers.forEach((value, key) => {
|
|
315
|
+
value.callback.forEach((cb) => {
|
|
316
|
+
this._pendingPublicSubscribe.push([value.params, cb, value.isOnce]);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
this._eventHandlers.delete(key);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
setTimeout(() => this.checkSocketStatus(), 0);
|
|
219
323
|
}
|
|
220
324
|
|
|
221
|
-
private
|
|
222
|
-
console.
|
|
325
|
+
private onPrivateClose(event: CloseEvent) {
|
|
326
|
+
console.log("private socket is closed");
|
|
327
|
+
if (this.privateIsReconnecting) return;
|
|
328
|
+
this._eventPrivateHandlers.forEach((value, key) => {
|
|
329
|
+
console.log(value);
|
|
223
330
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
331
|
+
value.callback.forEach((cb) => {
|
|
332
|
+
this._pendingPrivateSubscribe.push([value.params, cb, value.isOnce]);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
this._eventPrivateHandlers.delete(key);
|
|
229
336
|
});
|
|
337
|
+
this.authenticated = false;
|
|
230
338
|
|
|
231
|
-
this.
|
|
339
|
+
setTimeout(() => this.checkSocketStatus(), 0);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
private onPublicError(event: Event) {
|
|
343
|
+
console.error("public WebSocket error:", event);
|
|
344
|
+
this.publicIsReconnecting = false;
|
|
345
|
+
|
|
346
|
+
if (this.publicSocket.readyState === WebSocket.OPEN) {
|
|
347
|
+
this.publicSocket.close();
|
|
348
|
+
} else {
|
|
349
|
+
// retry connect
|
|
350
|
+
if (this._publicRetryCount > CONNECT_LIMIT) return;
|
|
351
|
+
setTimeout(() => {
|
|
352
|
+
console.log("retry connect: %s", this._publicRetryCount);
|
|
353
|
+
// this.createPublicSC(this.options);
|
|
354
|
+
this.reconnectPublic();
|
|
355
|
+
this._publicRetryCount++;
|
|
356
|
+
}, this._publicRetryCount * 1000);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
this.errorBoardscast(event, this._eventHandlers);
|
|
232
360
|
}
|
|
233
361
|
|
|
234
362
|
private onPrivateError(event: Event) {
|
|
235
363
|
console.error("Private WebSocket error:", event);
|
|
364
|
+
this.privateIsReconnecting = false;
|
|
236
365
|
|
|
237
|
-
this.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
366
|
+
if (this.privateSocket?.readyState === WebSocket.OPEN) {
|
|
367
|
+
this.privateSocket.close();
|
|
368
|
+
} else {
|
|
369
|
+
// retry connect
|
|
370
|
+
if (this._privateRetryCount > CONNECT_LIMIT) return;
|
|
371
|
+
setTimeout(() => {
|
|
372
|
+
console.log("retry connect: %s", this._privateRetryCount);
|
|
373
|
+
// this.createPublicSC(this.options);
|
|
374
|
+
this.reconnectPrivate();
|
|
375
|
+
this._privateRetryCount++;
|
|
376
|
+
}, this._privateRetryCount * 1000);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
this.errorBoardscast(event, this._eventPrivateHandlers);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private errorBoardscast(error: any, eventHandlers: Map<string, Topics>) {
|
|
383
|
+
eventHandlers.forEach((value) => {
|
|
384
|
+
value.callback.forEach((cb) => {
|
|
385
|
+
cb.onError?.(error);
|
|
386
|
+
});
|
|
242
387
|
});
|
|
243
388
|
}
|
|
244
389
|
|
|
@@ -368,7 +513,13 @@ export class WS {
|
|
|
368
513
|
});
|
|
369
514
|
this.publicSocket.send(JSON.stringify(subscribeMessage));
|
|
370
515
|
} else {
|
|
371
|
-
|
|
516
|
+
// 是否once,如果是once,则替换掉之前的callback
|
|
517
|
+
if (once) {
|
|
518
|
+
handler.callback = [callbacks];
|
|
519
|
+
this.publicSocket.send(JSON.stringify(subscribeMessage));
|
|
520
|
+
} else {
|
|
521
|
+
handler.callback.push(callbacks);
|
|
522
|
+
}
|
|
372
523
|
}
|
|
373
524
|
|
|
374
525
|
// this._subscriptionPublicTopics.push({params, cb: [cb]});
|
|
@@ -487,12 +638,27 @@ export class WS {
|
|
|
487
638
|
private reconnectPublic() {
|
|
488
639
|
if (this.publicIsReconnecting) return;
|
|
489
640
|
this.publicIsReconnecting = true;
|
|
490
|
-
console.log(
|
|
641
|
+
console.log(
|
|
642
|
+
`Reconnecting public in ${this.reconnectInterval / 1000} seconds...`
|
|
643
|
+
);
|
|
491
644
|
window.setTimeout(() => {
|
|
492
|
-
console.log("Reconnecting...");
|
|
493
|
-
// this.publicIsReconnecting = false;
|
|
645
|
+
console.log("Public Reconnecting...");
|
|
494
646
|
|
|
495
647
|
this.createPublicSC(this.options);
|
|
496
648
|
}, this.reconnectInterval);
|
|
497
649
|
}
|
|
650
|
+
|
|
651
|
+
private reconnectPrivate() {
|
|
652
|
+
if (!this.options.accountId) return;
|
|
653
|
+
if (this.privateIsReconnecting) return;
|
|
654
|
+
this.privateIsReconnecting = true;
|
|
655
|
+
console.log(
|
|
656
|
+
`Reconnecting private in ${this.reconnectInterval / 1000} seconds...`
|
|
657
|
+
);
|
|
658
|
+
window.setTimeout(() => {
|
|
659
|
+
console.log("Private Reconnecting...");
|
|
660
|
+
|
|
661
|
+
this.createPrivateSC(this.options);
|
|
662
|
+
}, this.reconnectInterval);
|
|
663
|
+
}
|
|
498
664
|
}
|