Wrap all websocket errors, reconnect earlier
This commit is contained in:
parent
8f5086227a
commit
584cedecff
3 changed files with 46 additions and 3 deletions
|
@ -225,6 +225,20 @@ describe('WebSocket-Resource', () => {
|
||||||
this.clock.next();
|
this.clock.next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('optionally disconnects if suspended', function thisNeeded1(done) {
|
||||||
|
const socket = new FakeSocket();
|
||||||
|
|
||||||
|
sinon.stub(socket, 'close').callsFake(() => done());
|
||||||
|
|
||||||
|
new WebSocketResource(socket as WebSocket, {
|
||||||
|
keepalive: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Just skip one hour immediately
|
||||||
|
this.clock.setSystemTime(NOW + 3600 * 1000);
|
||||||
|
this.clock.next();
|
||||||
|
});
|
||||||
|
|
||||||
it('allows resetting the keepalive timer', function thisNeeded2(done) {
|
it('allows resetting the keepalive timer', function thisNeeded2(done) {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
|
|
@ -336,9 +336,18 @@ async function _connectSocket(
|
||||||
|
|
||||||
reject(translatedError);
|
reject(translatedError);
|
||||||
});
|
});
|
||||||
client.on('connectFailed', error => {
|
client.on('connectFailed', e => {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
reject(error);
|
|
||||||
|
reject(
|
||||||
|
makeHTTPError(
|
||||||
|
'_connectSocket connectFailed',
|
||||||
|
0,
|
||||||
|
{},
|
||||||
|
e.toString(),
|
||||||
|
stack
|
||||||
|
)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import { typedArrayToArrayBuffer as toArrayBuffer } from '../Crypto';
|
||||||
|
|
||||||
import EventTarget from './EventTarget';
|
import EventTarget from './EventTarget';
|
||||||
|
|
||||||
|
import { isOlderThan } from '../util/timestamp';
|
||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
verb: string;
|
verb: string;
|
||||||
|
|
||||||
|
@ -264,6 +266,10 @@ type KeepAliveOptionsType = {
|
||||||
disconnect?: boolean;
|
disconnect?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const KEEPALIVE_INTERVAL_MS = 55000; // 55 seconds + 5 seconds for closing the
|
||||||
|
// socket above.
|
||||||
|
const MAX_KEEPALIVE_INTERVAL_MS = 300 * 1000; // 5 minutes
|
||||||
|
|
||||||
class KeepAlive {
|
class KeepAlive {
|
||||||
private keepAliveTimer: NodeJS.Timeout | undefined;
|
private keepAliveTimer: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
|
@ -275,6 +281,8 @@ class KeepAlive {
|
||||||
|
|
||||||
private wsr: WebSocketResource;
|
private wsr: WebSocketResource;
|
||||||
|
|
||||||
|
private lastAliveAt: number = Date.now();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
websocketResource: WebSocketResource,
|
websocketResource: WebSocketResource,
|
||||||
opts: KeepAliveOptionsType = {}
|
opts: KeepAliveOptionsType = {}
|
||||||
|
@ -295,9 +303,19 @@ class KeepAlive {
|
||||||
public send(): void {
|
public send(): void {
|
||||||
this.clearTimers();
|
this.clearTimers();
|
||||||
|
|
||||||
|
if (isOlderThan(this.lastAliveAt, MAX_KEEPALIVE_INTERVAL_MS)) {
|
||||||
|
window.log.info('WebSocketResources: disconnecting due to stale state');
|
||||||
|
this.wsr.close(
|
||||||
|
3001,
|
||||||
|
`Last keepalive request was too far in the past: ${this.lastAliveAt}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.disconnect) {
|
if (this.disconnect) {
|
||||||
// automatically disconnect if server doesn't ack
|
// automatically disconnect if server doesn't ack
|
||||||
this.disconnectTimer = setTimeout(() => {
|
this.disconnectTimer = setTimeout(() => {
|
||||||
|
window.log.info('WebSocketResources: disconnecting due to no response');
|
||||||
this.clearTimers();
|
this.clearTimers();
|
||||||
|
|
||||||
this.wsr.close(3001, 'No response to keepalive request');
|
this.wsr.close(3001, 'No response to keepalive request');
|
||||||
|
@ -315,9 +333,11 @@ class KeepAlive {
|
||||||
}
|
}
|
||||||
|
|
||||||
public reset(): void {
|
public reset(): void {
|
||||||
|
this.lastAliveAt = Date.now();
|
||||||
|
|
||||||
this.clearTimers();
|
this.clearTimers();
|
||||||
|
|
||||||
this.keepAliveTimer = setTimeout(() => this.send(), 55000);
|
this.keepAliveTimer = setTimeout(() => this.send(), KEEPALIVE_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearTimers(): void {
|
private clearTimers(): void {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue