Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/v1/signaling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ describe("Signaling websocket event handlers", () => {
expect(ws.setAutoReconnect).not.toHaveBeenCalled();
});

test("should clear ping interval and set isReady false on close", async () => {
test("should clear ping interval on close", async () => {
// Trigger open first to set up pingInterval
const openCallback = getWsCallback("open");
await openCallback();

const closeCallback = getWsCallback("close");
expect(closeCallback).toBeDefined();

closeCallback(4000);
closeCallback(1001);

expect((signaling as any).isReady).toBe(false);
});
Expand All @@ -207,6 +207,29 @@ describe("Signaling websocket event handlers", () => {
expect((signaling as any).ws).toBeNull();
expect((signaling as any).isReady).toBe(false);
});

test("should not disconnect on the retryable close code 1001", async () => {
const closeCallback = getWsCallback("close");
expect(closeCallback).toBeDefined();

closeCallback(1001);

expect((signaling as any).ws).not.toBeNull();
const ws = (signaling as any).ws;
expect(ws.setAutoReconnect).not.toHaveBeenCalled();
});

test.each([4409, 1011, 4000])("should disable auto-reconnect and disconnect on close code %d", async (code) => {
const ws = (signaling as any).ws;
const closeCallback = getWsCallback("close");
expect(closeCallback).toBeDefined();

closeCallback(code);

expect(ws.setAutoReconnect).toHaveBeenCalledWith(false);
expect((signaling as any).ws).toBeNull();
expect((signaling as any).isReady).toBe(false);
});
});

describe("Signaling disconnect", () => {
Expand Down
15 changes: 13 additions & 2 deletions src/v1/signaling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ const FATAL_HANDSHAKE_ERRORS: Record<string, { status: number; logMessage: strin
},
};

/**
* Close codes that should trigger a reconnect on this same client instance.
* Every other code, including ones this SDK doesn't recognize, tears the
* connection down instead of retrying it.
*/
const RETRY_CLOSE_CODES = new Set([1001]);

class Signaling extends EventEmitter {
private defaultWebsocketUrl: string = "wss://gateway.pv.prod.global.aws.bandwidth.com/prod/gateway-service/api/v1/endpoints";
private ws: JsonRpcClient | null = null;
Expand Down Expand Up @@ -143,8 +150,12 @@ class Signaling extends EventEmitter {
if (this.pingInterval) {
clearInterval(this.pingInterval);
}
if (code == 1000) {
// We were asked to go away and not come back. We should disconnect without calling leave.
if (!RETRY_CLOSE_CODES.has(code)) {
// rpc-websockets schedules its own reconnect synchronously, before it
// fires the "close" event we're handling here, so setAutoReconnect(false)
// alone is too late — the pending timer has to be cleared directly.
clearTimeout((ws as any).reconnect_timer_id);
ws.setAutoReconnect(false);
this._disconnect(false);
}
this.isReady = false;
Expand Down