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();
|
||||
});
|
||||
|
||||
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) {
|
||||
const startTime = Date.now();
|
||||
|
||||
|
|
|
@ -336,9 +336,18 @@ async function _connectSocket(
|
|||
|
||||
reject(translatedError);
|
||||
});
|
||||
client.on('connectFailed', error => {
|
||||
client.on('connectFailed', e => {
|
||||
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 { isOlderThan } from '../util/timestamp';
|
||||
|
||||
class Request {
|
||||
verb: string;
|
||||
|
||||
|
@ -264,6 +266,10 @@ type KeepAliveOptionsType = {
|
|||
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 {
|
||||
private keepAliveTimer: NodeJS.Timeout | undefined;
|
||||
|
||||
|
@ -275,6 +281,8 @@ class KeepAlive {
|
|||
|
||||
private wsr: WebSocketResource;
|
||||
|
||||
private lastAliveAt: number = Date.now();
|
||||
|
||||
constructor(
|
||||
websocketResource: WebSocketResource,
|
||||
opts: KeepAliveOptionsType = {}
|
||||
|
@ -295,9 +303,19 @@ class KeepAlive {
|
|||
public send(): void {
|
||||
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) {
|
||||
// automatically disconnect if server doesn't ack
|
||||
this.disconnectTimer = setTimeout(() => {
|
||||
window.log.info('WebSocketResources: disconnecting due to no response');
|
||||
this.clearTimers();
|
||||
|
||||
this.wsr.close(3001, 'No response to keepalive request');
|
||||
|
@ -315,9 +333,11 @@ class KeepAlive {
|
|||
}
|
||||
|
||||
public reset(): void {
|
||||
this.lastAliveAt = Date.now();
|
||||
|
||||
this.clearTimers();
|
||||
|
||||
this.keepAliveTimer = setTimeout(() => this.send(), 55000);
|
||||
this.keepAliveTimer = setTimeout(() => this.send(), KEEPALIVE_INTERVAL_MS);
|
||||
}
|
||||
|
||||
private clearTimers(): void {
|
||||
|
|
Loading…
Reference in a new issue