mirror of
https://github.com/ruvnet/RuView.git
synced 2026-04-28 05:59:32 +00:00
fix(mobile): clean up sockets when simulation starts
When the server URL is cleared, close the active WebSocket and cancel pending reconnects so simulation mode does not race with stale network state. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
2a05378bd2
commit
59f44dcfe5
2 changed files with 63 additions and 0 deletions
|
|
@ -109,6 +109,62 @@ describe('WsService', () => {
|
|||
expect(ws.getStatus()).toBe('simulated');
|
||||
ws.disconnect();
|
||||
});
|
||||
|
||||
it('cleans up active sockets and pending reconnects when switching to simulation mode', () => {
|
||||
const sockets: MockWebSocketInstance[] = [];
|
||||
const OrigWebSocket = globalThis.WebSocket;
|
||||
|
||||
class MockWebSocket {
|
||||
static OPEN = 1;
|
||||
static CONNECTING = 0;
|
||||
static CLOSED = 3;
|
||||
readyState = MockWebSocket.OPEN;
|
||||
onopen: (() => void) | null = null;
|
||||
onclose: ((event: { code: number }) => void) | null = null;
|
||||
onerror: (() => void) | null = null;
|
||||
onmessage: (() => void) | null = null;
|
||||
close = jest.fn((code?: number) => {
|
||||
this.readyState = MockWebSocket.CLOSED;
|
||||
this.onclose?.({ code: code ?? 1000 });
|
||||
});
|
||||
|
||||
constructor(_url: string) {
|
||||
sockets.push(this as unknown as MockWebSocketInstance);
|
||||
}
|
||||
}
|
||||
|
||||
type MockWebSocketInstance = {
|
||||
onclose: ((event: { code: number }) => void) | null;
|
||||
close: jest.Mock;
|
||||
};
|
||||
|
||||
globalThis.WebSocket = MockWebSocket as any;
|
||||
|
||||
try {
|
||||
const ws = createWsService();
|
||||
ws.connect('http://localhost:3000');
|
||||
expect(sockets).toHaveLength(1);
|
||||
|
||||
ws.connect('');
|
||||
expect(sockets[0].close).toHaveBeenCalledWith(1000, 'switch to simulation');
|
||||
expect(ws.getStatus()).toBe('simulated');
|
||||
ws.disconnect();
|
||||
|
||||
const wsWithReconnect = createWsService();
|
||||
wsWithReconnect.connect('http://localhost:3000');
|
||||
expect(sockets).toHaveLength(2);
|
||||
|
||||
sockets[1].onclose?.({ code: 1006 });
|
||||
wsWithReconnect.connect('');
|
||||
|
||||
jest.advanceTimersByTime(60_000);
|
||||
expect(sockets).toHaveLength(2);
|
||||
expect(wsWithReconnect.getStatus()).toBe('simulated');
|
||||
wsWithReconnect.disconnect();
|
||||
} finally {
|
||||
globalThis.WebSocket = OrigWebSocket;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('subscribe and unsubscribe', () => {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ class WsService {
|
|||
this.reconnectAttempt = 0;
|
||||
|
||||
if (!url) {
|
||||
this.clearReconnectTimer();
|
||||
if (this.ws) {
|
||||
const socket = this.ws;
|
||||
this.ws = null;
|
||||
socket.onclose = null;
|
||||
socket.close(1000, 'switch to simulation');
|
||||
}
|
||||
this.handleStatusChange('simulated');
|
||||
this.startSimulation();
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue