Skip to content

Commit 1fdaf00

Browse files
authored
don't endlessly poll websocket when disconnected due to suspension (#5464)
1 parent 8c1d1b1 commit 1fdaf00

File tree

2 files changed

+23
-31
lines changed

2 files changed

+23
-31
lines changed

resources/scripts/components/server/WebsocketHandler.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ export default () => {
3434

3535
socket.on('auth success', () => setConnectionState(true));
3636
socket.on('SOCKET_CLOSE', () => setConnectionState(false));
37+
socket.on('SOCKET_CONNECT_ERROR', () => {
38+
setError('Failed to connect to websocket instance after multiple attempts: try refreshing the page.');
39+
});
3740
socket.on('SOCKET_ERROR', () => {
3841
setError('connecting');
3942
setConnectionState(false);

resources/scripts/plugins/Websocket.ts

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ import Sockette from 'sockette';
22
import { EventEmitter } from 'events';
33

44
export class Websocket extends EventEmitter {
5-
// Timer instance for this socket.
6-
private timer: any = null;
7-
8-
// The backoff for the timer, in milliseconds.
9-
private backoff = 5000;
10-
115
// The socket instance being tracked.
126
private socket: Sockette | null = null;
137

@@ -26,6 +20,8 @@ export class Websocket extends EventEmitter {
2620
this.url = url;
2721

2822
this.socket = new Sockette(`${this.url}`, {
23+
timeout: 1000,
24+
maxAttempts: 20,
2925
onmessage: (e) => {
3026
try {
3127
const { event, args } = JSON.parse(e.data);
@@ -35,30 +31,29 @@ export class Websocket extends EventEmitter {
3531
}
3632
},
3733
onopen: () => {
38-
// Clear the timers, we managed to connect just fine.
39-
this.timer && clearTimeout(this.timer);
40-
this.backoff = 5000;
41-
4234
this.emit('SOCKET_OPEN');
4335
this.authenticate();
4436
},
4537
onreconnect: () => {
46-
this.emit('SOCKET_RECONNECT');
47-
this.authenticate();
38+
// We return code 4409 from Wings when a server is suspended. We've
39+
// gone ahead and reserved 4400 as well here for future expansion without
40+
// having to loop back around.
41+
//
42+
// If either of those codes is returned go ahead and abort here. Unfortunately
43+
// the underlying sockette logic always calls reconnect for any code that isn't
44+
// 1000/1001/1003, which is painful but we can just stop the flow here.
45+
// @ts-expect-error code is actually present here.
46+
if (evt.code === 4409 || evt.code === 4400) {
47+
this.close(1000);
48+
} else {
49+
this.emit('SOCKET_RECONNECT');
50+
}
4851
},
4952
onclose: () => this.emit('SOCKET_CLOSE'),
5053
onerror: (error) => this.emit('SOCKET_ERROR', error),
54+
onmaximum: () => this.emit('SOCKET_CONNECT_ERROR'),
5155
});
5256

53-
this.timer = setTimeout(() => {
54-
this.backoff = this.backoff + 2500 >= 20000 ? 20000 : this.backoff + 2500;
55-
this.socket && this.socket.close();
56-
clearTimeout(this.timer);
57-
58-
// Re-attempt connecting to the socket.
59-
this.connect(url);
60-
}, this.backoff);
61-
6257
return this;
6358
}
6459

@@ -83,24 +78,18 @@ export class Websocket extends EventEmitter {
8378
close(code?: number, reason?: string) {
8479
this.url = null;
8580
this.token = '';
86-
this.socket && this.socket.close(code, reason);
81+
this.socket?.close(code, reason);
8782
}
8883

8984
open() {
90-
this.socket && this.socket.open();
85+
this.socket?.open();
9186
}
9287

9388
reconnect() {
94-
this.socket && this.socket.reconnect();
89+
this.socket?.reconnect();
9590
}
9691

9792
send(event: string, payload?: string | string[]) {
98-
this.socket &&
99-
this.socket.send(
100-
JSON.stringify({
101-
event,
102-
args: Array.isArray(payload) ? payload : [payload],
103-
})
104-
);
93+
this.socket?.json({ event, args: Array.isArray(payload) ? payload : [payload] });
10594
}
10695
}

0 commit comments

Comments
 (0)