diff --git a/client/src/AdriftClient.ts b/client/src/AdriftClient.ts index 610d103..512fb18 100644 --- a/client/src/AdriftClient.ts +++ b/client/src/AdriftClient.ts @@ -83,8 +83,9 @@ export class AdriftBareClient extends Client { onReadyState(WebSocket.OPEN); ws.dispatchEvent(new Event("open")); }, - () => { + (code: number, reason: string, wasClean: boolean) => { onReadyState(WebSocket.CLOSED); + ws.dispatchEvent(new CloseEvent("close", { code, reason, wasClean })); }, (data) => { ws.dispatchEvent( diff --git a/client/src/Connection.ts b/client/src/Connection.ts index 37b0ddd..41d3864 100644 --- a/client/src/Connection.ts +++ b/client/src/Connection.ts @@ -6,10 +6,14 @@ import { HTTPResponsePayload, S2CRequestType, S2CRequestTypes, + S2CWSClosePayload, Transport, } from "protocol"; -type OpenWSMeta = { onclose: () => void; onmessage: (data: any) => void }; +type OpenWSMeta = { + onclose: (code: number, reason: string, wasClean: boolean) => void; + onmessage: (data: any) => void; +}; export class Connection { requestCallbacks: Record = {}; @@ -89,6 +93,21 @@ export class Connection { break; } + case S2CRequestTypes.WSClose: { + const socketMeta = this.openSockets[requestID]; + if (!socketMeta) return; + const payload: S2CWSClosePayload = JSON.parse( + new TextDecoder().decode(data.slice(cursor)) + ); + socketMeta.onclose( + payload.code || 1005, + payload.reason || "", + "wasClean" in payload ? Boolean(payload.wasClean) : false + ); + delete this.openSockets[requestID]; + break; + } + default: break; } @@ -130,7 +149,7 @@ export class Connection { wsconnect( url: URL, onopen: () => void, - onclose: () => void, + onclose: (code: number, reason: string, wasClean: boolean) => void, onmessage: (data: any) => void ): { send: (data: any) => void; @@ -139,13 +158,16 @@ export class Connection { const payload: C2SWSOpenPayload = { url: url.toString() }; const payloadJSON = JSON.stringify(payload); let seq = this.nextSeq(); + // todo: onerror + const closeWithError = () => onclose(1006, "", false); + this.send( seq, new TextEncoder().encode(payloadJSON), C2SRequestTypes.WSOpen ).catch((e) => { console.error(e); - onclose(); + closeWithError(); }); // this can't be async, just call onopen when opened @@ -153,6 +175,7 @@ export class Connection { return { send: (data) => { + console.log("Reached Connection.ts send!"); if (!this.openSockets[seq]) { throw new Error("send on closed socket"); } diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 223e2eb..418c3ba 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -158,14 +158,16 @@ (window as any).bare = new BareClient(); (window as any).myWsTest = () => { + // const url = "wss://ws.postman-echo.com/raw"; + const url = "ws://127.0.0.1:3002/"; const ws = ((window as any).ws = ( (window as any).bare as BareClient - ).createWebSocket("wss://ws.postman-echo.com/raw", [], {})); + ).createWebSocket(url, [], {})); ws.onopen = () => console.log("onopen"); ws.addEventListener("open", () => console.log("open listener")); ws.onclose = () => console.error(new Error("onclose")); - ws.addEventListener("close", () => console.log("close listener")); - ws.onmessage = console.log; + ws.addEventListener("close", (e) => console.log("close listener", e)); + ws.onmessage = (e) => console.log("message", e); };