

















@@ -0,0 +1,64 @@
1+type WebSocketOpenHandle = {
2+close?: () => void;
3+off?: (event: "open" | "error" | "close", listener: (...args: unknown[]) => void) => void;
4+on?: (event: "error", listener: (...args: unknown[]) => void) => void;
5+once: (event: "open" | "error" | "close", listener: (...args: unknown[]) => void) => void;
6+terminate?: () => void;
7+};
8+9+export function waitForWebSocketOpen(
10+ws: WebSocketOpenHandle,
11+timeoutMs: number,
12+message = "gateway ws open timeout",
13+): Promise<void> {
14+return new Promise((resolve, reject) => {
15+let settled = false;
16+let timer: ReturnType<typeof setTimeout>;
17+18+const cleanup = () => {
19+clearTimeout(timer);
20+ws.off?.("open", onOpen);
21+ws.off?.("error", onError);
22+};
23+const resolveOpen = () => {
24+if (settled) {
25+return;
26+}
27+settled = true;
28+cleanup();
29+resolve();
30+};
31+const rejectOpen = (error: unknown) => {
32+if (settled) {
33+return;
34+}
35+settled = true;
36+cleanup();
37+reject(error instanceof Error ? error : new Error(String(error)));
38+};
39+const onOpen = () => resolveOpen();
40+const onError = (error: unknown) => rejectOpen(error);
41+timer = setTimeout(() => {
42+const consumeAbortError = () => {};
43+const removeAbortErrorConsumer = () => {
44+ws.off?.("error", consumeAbortError);
45+ws.off?.("close", removeAbortErrorConsumer);
46+};
47+try {
48+ws.off?.("error", onError);
49+ws.on?.("error", consumeAbortError);
50+ws.once?.("close", removeAbortErrorConsumer);
51+ws.terminate?.();
52+if (typeof ws.terminate !== "function") {
53+ws.close?.();
54+}
55+} finally {
56+rejectOpen(new Error(message));
57+}
58+}, timeoutMs);
59+60+timer.unref?.();
61+ws.once("open", onOpen);
62+ws.once("error", onError);
63+});
64+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。