How to reconnect to websocket after close connection
JavascriptHtmlWebsocketsocket.ioJavascript Problem Overview
I construct my websocket connection with this code (e.g.):
var socket = new WebSocket("ws://94.12.176.177:8080");
And I close the connection with this one:
socket.close();
But how do I reestablish connection?
I've done some research and tried several methods. This question could not help me: https://stackoverflow.com/questions/5898327/socket-io-reconnect-on-disconnect It's the only result which close to what I'm looking for.
The reason I want to do this is to allow users to stop sending data to the web temporary, and resending again after a period of time. Without reconnection, user have to refresh the page in order to resend. This may cause some data lost. Thank you.
Javascript Solutions
Solution 1 - Javascript
When the server closes the connection, the client does not try to reconnect. With some JS frameworks maybe, but the question was, at the time of this answer, tagged as plain Vanilla JS.
I'm a bit frustrated because the accepted, upvoted answer is plainly wrong, and it cost me some additional time while finding the correct solution.
Which is here: https://stackoverflow.com/questions/3780511/reconnection-of-client-when-server-reboots-in-websocket
Solution 2 - Javascript
I found a great solution on this page: sam-low.com
Once the original connection has been closed, you need to create a new WebSocket object with new event listeners
function startWebsocket() {
var ws = new WebSocket('ws://localhost:8080')
ws.onmessage = function(e){
console.log('websocket message event:', e)
}
ws.onclose = function(){
// connection closed, discard old websocket and create a new one in 5s
ws = null
setTimeout(startWebsocket, 5000)
}
}
startWebsocket();
Note that if there’s a problem reconnecting, the new WebSocket object will still receive another close event, meaning that onclose()
will be executed even if it never technically opened. That’s why the delay of five seconds is sensible - without it you could find yourself creating and destroying thousands of websocket connections at a rate that would probably break something.
Solution 3 - Javascript
> NOTE: The question is tagged socket.io
so this answer is specifically regarding socket.io
.
> As many people have pointed out, this answer doesn't apply to vanilla websockets, which will not attempt to reconnect under any circumstances.
Websockets will not automatically try to reconnect. You'll have to recreate the socket in order to get a new connection. The only problem with that is you'll have to reattach your handlers.
But really, websockets are designed to stay open.
A better method would be to have the server close the connection. This way the websocket will fire an onclose
event but will continue attempting to make the connection. When the server is listening again the connection will be automatically reestablished.
Solution 4 - Javascript
Flawless implementation:
var socket;
const socketMessageListener = (event) => {
console.log(event.data);
};
const socketOpenListener = (event) => {
console.log('Connected');
socket.send('hello');
};
const socketCloseListener = (event) => {
if (socket) {
console.error('Disconnected.');
}
socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', socketOpenListener);
socket.addEventListener('message', socketMessageListener);
socket.addEventListener('close', socketCloseListener);
};
socketCloseListener();
To test it:
setTimeout(()=>{
socket.close();
},5000);
Edit: Take note of the Exponential Backoff implementation (at the linked thread by top comment: https://stackoverflow.com/a/37038217/8805423), not in above code BUT VERY VERY CRUCIAL.
Edit again: Check out back
from primus
: https://www.npmjs.com/package/back, it's a flexible sexy implementation.
Solution 5 - Javascript
function wsConnection(url){
var ws = new WebSocket(url);
var s = (l)=>console.log(l);
ws.onopen = m=>s(" CONNECTED")
ws.onmessage = m=>s(" RECEIVED: "+JSON.parse(m.data))
ws.onerror = e=>s(" ERROR")
ws.onclose = e=>{
s(" CONNECTION CLOSED");
setTimeout((function() {
var ws2 = new WebSocket(ws.url);
ws2.onopen=ws.onopen;
ws2.onmessage = ws.onmessage;
ws2.onclose = ws.onclose;
ws2.onerror = ws.onerror;
ws = ws2
}
).bind(this), 5000)
}
var f = m=>ws.send(JSON.stringify(m)) || "Sent: "+m;
f.ping = ()=>ws.send(JSON.stringify("ping"));
f.close = ()=>ws.close();
return f
}
c=new wsConnection('wss://echo.websocket.org');
setTimeout(()=>c("Hello world...orld...orld..orld...d"),5000);
setTimeout(()=>c.close(),10000);
setTimeout(()=>c("I am still alive!"),20000);
<pre>
This code will create a websocket which will
reconnect automatically after 5 seconds from disconnection.
An automatic disconnection is simulated after 10 seconds.