From a3d53595f6dd11f2f59cdf0086b3d7ce558a2fdd Mon Sep 17 00:00:00 2001 From: Hanssen0 Date: Sat, 12 Oct 2024 18:32:44 +0800 Subject: [PATCH] fix(core): reopen websocket --- .changeset/brave-keys-relate.md | 5 ++ .../core/src/client/transports/webSocket.ts | 90 ++++++++++--------- 2 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 .changeset/brave-keys-relate.md diff --git a/.changeset/brave-keys-relate.md b/.changeset/brave-keys-relate.md new file mode 100644 index 00000000..f9041ac2 --- /dev/null +++ b/.changeset/brave-keys-relate.md @@ -0,0 +1,5 @@ +--- +"@ckb-ccc/core": patch +--- + +fix(core): reopen websocket diff --git a/packages/core/src/client/transports/webSocket.ts b/packages/core/src/client/transports/webSocket.ts index afa601d3..58d60e45 100644 --- a/packages/core/src/client/transports/webSocket.ts +++ b/packages/core/src/client/transports/webSocket.ts @@ -10,7 +10,8 @@ export class TransportWebSocket implements Transport { ReturnType, ] > = new Map(); - private socket?: Promise; + private socket?: WebSocket; + private openSocket?: Promise; constructor( private readonly url: string, @@ -18,55 +19,56 @@ export class TransportWebSocket implements Transport { ) {} request(data: JsonRpcPayload) { - const socket = (this.socket ?? Promise.resolve(undefined)).then( - (existed) => { - if ( - existed && - existed.readyState !== existed.CLOSING && - existed.readyState !== existed.CLOSED - ) { - return existed; + const socket = (() => { + if ( + this.socket && + this.socket.readyState !== this.socket.CLOSING && + this.socket.readyState !== this.socket.CLOSED && + this.openSocket + ) { + return this.openSocket; + } + const socket = new WebSocket(this.url); + const onMessage = ({ data }: { data: string }) => { + const res = JSON.parse(data); + if (typeof res !== "object" || res === null) { + throw new Error(`Unknown response ${data}`); } - const socket = new WebSocket(this.url); - const onMessage = ({ data }: { data: string }) => { - const res = JSON.parse(data); - if (typeof res !== "object" || res === null) { - throw new Error(`Unknown response ${data}`); - } + const req = this.ongoing.get(res.id); + if (!req) { + return; + } + const [resolve, _, timeout] = req; + clearTimeout(timeout); + this.ongoing.delete(res.id); - const req = this.ongoing.get(res.id); - if (!req) { - return; - } - const [resolve, _, timeout] = req; + resolve(res); + }; + const onClose = () => { + this.ongoing.forEach(([_, reject, timeout]) => { clearTimeout(timeout); - this.ongoing.delete(res.id); - - resolve(res); - }; - const onClose = () => { - this.ongoing.forEach(([_, reject, timeout]) => { - clearTimeout(timeout); - reject(new Error("Connection closed")); - }); - this.ongoing.clear(); - }; + reject(new Error("Connection closed")); + }); + this.ongoing.clear(); + }; - socket.onclose = onClose; - socket.onerror = onClose; - socket.onmessage = onMessage; + socket.onclose = onClose; + socket.onerror = onClose; + socket.onmessage = onMessage; - this.socket = new Promise((resolve) => { - if (socket.readyState === socket.OPEN) { - resolve(undefined); - } else { - socket.onopen = resolve; - } - }).then(() => socket); - return this.socket; - }, - ); + this.socket = socket; + this.openSocket = new Promise((resolve) => { + if (socket.readyState === socket.OPEN) { + resolve(socket); + } else { + socket.onopen = () => { + resolve(socket); + }; + } + }); + return this.openSocket; + })(); return new Promise((resolve, reject) => { const req: [