1
Fork 0

Implement a client-side timeout.

We already had a server-side timeout, but it didn't prevent
a client from hanging when it lost connectivity with the server.
This commit is contained in:
Juliusz Chroboczek 2024-06-10 19:45:23 +02:00
parent ee18b60226
commit 242875e55c
1 changed files with 32 additions and 1 deletions

View File

@ -140,9 +140,21 @@ function ServerConnection() {
* userdata is a convenient place to attach data to a ServerConnection. * userdata is a convenient place to attach data to a ServerConnection.
* It is not used by the library. * It is not used by the library.
* *
* @type{Object<unknown,unknown>} * @type {Object<unknown,unknown>}
*/ */
this.userdata = {}; this.userdata = {};
/**
* The time at which we last received a message from the server.
*
* @type {number}
*/
this.lastServerMessage = null;
/**
* The interval handler which checks for liveness.
*
* @type {number}
*/
this.pingHandler = null;
/* Callbacks */ /* Callbacks */
@ -308,6 +320,20 @@ ServerConnection.prototype.connect = function(url) {
sc.socket = new WebSocket(url); sc.socket = new WebSocket(url);
this.pingHandler = setInterval(e => {
if(!sc.lastServerMessage) {
sc.error(new Error('Timeout'));
return;
}
let d = new Date().valueOf() - sc.lastServerMessage;
if(d > 65000) {
sc.error(new Error('Timeout'));
return;
}
if(sc.version && d >= 15000)
sc.send({type: 'ping'});
}, 10000);
this.socket.onerror = function(e) { this.socket.onerror = function(e) {
if(sc.onerror) if(sc.onerror)
sc.onerror.call(sc, new Error('Socket error: ' + e)); sc.onerror.call(sc, new Error('Socket error: ' + e));
@ -343,6 +369,10 @@ ServerConnection.prototype.connect = function(url) {
sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '', ''); sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '', '');
sc.group = null; sc.group = null;
sc.username = null; sc.username = null;
if(sc.pingHandler) {
clearInterval(sc.pingHandler);
sc.pingHandler = null;
}
if(sc.onclose) if(sc.onclose)
sc.onclose.call(sc, e.code, e.reason); sc.onclose.call(sc, e.code, e.reason);
}; };
@ -358,6 +388,7 @@ ServerConnection.prototype.connect = function(url) {
sc.error(new Error("Server didn't send handshake")); sc.error(new Error("Server didn't send handshake"));
return; return;
} }
sc.lastServerMessage = new Date().valueOf();
switch(m.type) { switch(m.type) {
case 'handshake': { case 'handshake': {
if((m.version instanceof Array) && m.version.includes('2')) { if((m.version instanceof Array) && m.version.includes('2')) {