Here my websocket.js code:
let ws = null;
let connected = false;
const TIMER_RECONNECTION = 10000;
const TIMER_TIMEOUT = 8000;
setInterval(reconnect, TIMER_RECONNECTION);
const extractHostname = function (url) {
let hostname;
if (url.indexOf("://") > -1) hostname = url.split("/")[2];
else hostname = url.split("/")[0];
hostname = hostname.split(":")[0];
hostname = hostname.split("?")[0];
return hostname;
};
const composeWsAddress = function (address) {
let scheme = "ws";
if (document.location.protocol === "https:") scheme += "s";
return scheme + "://" + address + ":8000/ws";
};
const open = function (address) {
console.log("Connecting...");
delete ws;
ws = new WebSocket(address);
ws.onopen = onOpen;
ws.onclose = onClose;
ws.onmessage = onMessage;
setTimeout(() => {
if (ws && ws.readyState === WebSocket.CONNECTING) {
ws.close();
connected = false;
console.log("aborted!");
return;
}
}, TIMER_TIMEOUT);
};
let onOpen = function() {
console.log("success!");
connected = true;
};
let onClose = function() {
ws = null;
connected = false;
};
let onMessage = function(event) {
};
WebSocketClient = {
init: function() { }
};
function reconnect() {
if (connected === false) {
const address = composeWsAddress(extractHostname(location.href));
open(address);
}
}
$(function() {
WebSocketClient.init();
reconnect();
});
The expected behavior is:
- try to connect to the websocket server
- if the connection is not done within 8 seconds, abort it
- every 10 seconds check the connection state: if not connected retry
It works quite well:
Connecting...
aborted! [after 8 seconds]
Connecting... [after 2 more seconds]
aborted! [after 8 seconds]
Connecting... [after 2 more seconds]
aborted! [after 8 seconds]
success!
If it fails for a quite long time, not sure how much, say several minutes, then when the server it's available it continues to fail again for minutes before connecting. Reloading the page does not help.
The only way I found to connect immediately (after this situation) is to close and open again the whole browser (Firefox).
But I cannot ask the user to do this! How to improve my code to avoid such a behavior?