handle server WSClose

This commit is contained in:
Spencer Pogorzelski 2023-08-14 11:13:17 -07:00
parent 3539de7c18
commit ce4a642542
3 changed files with 33 additions and 7 deletions

View file

@ -83,8 +83,9 @@ export class AdriftBareClient extends Client {
onReadyState(WebSocket.OPEN); onReadyState(WebSocket.OPEN);
ws.dispatchEvent(new Event("open")); ws.dispatchEvent(new Event("open"));
}, },
() => { (code: number, reason: string, wasClean: boolean) => {
onReadyState(WebSocket.CLOSED); onReadyState(WebSocket.CLOSED);
ws.dispatchEvent(new CloseEvent("close", { code, reason, wasClean }));
}, },
(data) => { (data) => {
ws.dispatchEvent( ws.dispatchEvent(

View file

@ -6,10 +6,14 @@ import {
HTTPResponsePayload, HTTPResponsePayload,
S2CRequestType, S2CRequestType,
S2CRequestTypes, S2CRequestTypes,
S2CWSClosePayload,
Transport, Transport,
} from "protocol"; } 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 { export class Connection {
requestCallbacks: Record<number, Function> = {}; requestCallbacks: Record<number, Function> = {};
@ -89,6 +93,21 @@ export class Connection {
break; 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: default:
break; break;
} }
@ -130,7 +149,7 @@ export class Connection {
wsconnect( wsconnect(
url: URL, url: URL,
onopen: () => void, onopen: () => void,
onclose: () => void, onclose: (code: number, reason: string, wasClean: boolean) => void,
onmessage: (data: any) => void onmessage: (data: any) => void
): { ): {
send: (data: any) => void; send: (data: any) => void;
@ -139,13 +158,16 @@ export class Connection {
const payload: C2SWSOpenPayload = { url: url.toString() }; const payload: C2SWSOpenPayload = { url: url.toString() };
const payloadJSON = JSON.stringify(payload); const payloadJSON = JSON.stringify(payload);
let seq = this.nextSeq(); let seq = this.nextSeq();
// todo: onerror
const closeWithError = () => onclose(1006, "", false);
this.send( this.send(
seq, seq,
new TextEncoder().encode(payloadJSON), new TextEncoder().encode(payloadJSON),
C2SRequestTypes.WSOpen C2SRequestTypes.WSOpen
).catch((e) => { ).catch((e) => {
console.error(e); console.error(e);
onclose(); closeWithError();
}); });
// this can't be async, just call onopen when opened // this can't be async, just call onopen when opened
@ -153,6 +175,7 @@ export class Connection {
return { return {
send: (data) => { send: (data) => {
console.log("Reached Connection.ts send!");
if (!this.openSockets[seq]) { if (!this.openSockets[seq]) {
throw new Error("send on closed socket"); throw new Error("send on closed socket");
} }

View file

@ -158,14 +158,16 @@
(window as any).bare = new BareClient(); (window as any).bare = new BareClient();
(window as any).myWsTest = () => { (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 = ( const ws = ((window as any).ws = (
(window as any).bare as BareClient (window as any).bare as BareClient
).createWebSocket("wss://ws.postman-echo.com/raw", [], {})); ).createWebSocket(url, [], {}));
ws.onopen = () => console.log("onopen"); ws.onopen = () => console.log("onopen");
ws.addEventListener("open", () => console.log("open listener")); ws.addEventListener("open", () => console.log("open listener"));
ws.onclose = () => console.error(new Error("onclose")); ws.onclose = () => console.error(new Error("onclose"));
ws.addEventListener("close", () => console.log("close listener")); ws.addEventListener("close", (e) => console.log("close listener", e));
ws.onmessage = console.log; ws.onmessage = (e) => console.log("message", e);
}; };
</script> </script>