SocketCluster / socketcluster-client

JavaScript client for SocketCluster
MIT License
291 stars 92 forks source link

autoConnect and autoReconnect do not work #98

Closed skarahoda closed 6 years ago

skarahoda commented 6 years ago

Hi,

When my server is down, my client programs rise socket hang up exception and then they terminate. I looked into codes a bit. Websocket client gives connection refused error. Then socketcluster create a socket hang up excpetion. I think it should start reconnection mechanism when websocket give connection refused error.

Thanks,

Here is my sample code:

var socketCluster = require('socketcluster-client');
var options = {
    hostname: 'localhost',
    port: '8000',
    autoConnect: true,
    autoReconnect: true
};

var socket = socketCluster.connect(options);

socket.on('connect', onConnect);

function onConnect() {
    console.log('connected');
}

socket.on('disconnection', onDisconnect);

function onDisconnect(){
    console.log('disconnected');
}
DarkMukke commented 6 years ago

I think the auto reconnect only works after a first successful connection. Otherwise it would spam connection refused errors.

jondubois commented 6 years ago

@skarahoda @DarkMukke It should still try to reconnect; even if the first connection attempt failed.

The socketcluster-client uses a randomized exponential backoff algorithm to prevent all clients from trying to reconnect at the exact same time (which can overload the server). This is mostly useful in situations where an entire server crashes and all clients try to reconnect at once.

Exponential backoff means that every time a connect attempt fails in a sequence, it will wait longer before it tries to reconnect again (up to a specific maximum timeout period)... But it should never stop retrying until you manually call socket.disconnect().

The reconnect options are entirely configurable on the client so you can make it retry faster, sooner and with a smaller maximum backoff interval and less randomness if necessary. Search for autoReconnectOptions on this page: https://socketcluster.io/#!/docs/api-socketcluster-client

skarahoda commented 6 years ago

@DarkMukke @jondubois I tried two cases:

1) open client when the server is down 2) open client when the server is up. When the client is connected, close the server.

For both cases I expected the client tries to connect server repeatedly, However, the socketcluster-client module throws an exception:

/root/socketCluster/client/node_modules/socketcluster-client/lib/scsocket.js:532 throw err; ^ SocketProtocolError: Socket hung up at SCSocket._onSCClose (/root/socketCluster/client/node_modules/socketcluster-client/lib/scsocket.js:629:15) at SCTransport. (/root/socketCluster/client/node_modules/socketcluster-client/lib/scsocket.js:280:12) at SCTransport.Emitter.emit (/root/socketCluster/client/node_modules/component-emitter/index.js:133:20) at SCTransport._onClose (/root/socketCluster/client/node_modules/socketcluster-client/lib/sctransport.js:203:28) at WebSocket.wsSocket.onclose (/root/socketCluster/client/node_modules/socketcluster-client/lib/sctransport.js:101:10) at WebSocket.onClose (/root/socketCluster/client/node_modules/ws/lib/EventTarget.js:103:16) at emitTwo (events.js:106:13) at WebSocket.emit (events.js:194:7) at WebSocket.emitClose (/root/socketCluster/client/node_modules/ws/lib/WebSocket.js:224:10) at _receiver.cleanup (/root/socketCluster/client/node_modules/ws/lib/WebSocket.js:210:41)

I debug the module and I realized the websocket module in socketcluster fires disconnection event. When the event is fired, socketcluster module throws an exception.

Maybe I am wrong. Please try my simple example client code. I'm sure you will find the problem quickly.

Here is also server code:

var http = require('http');
var socketClusterServer = require('socketcluster-server');
var httpServer = http.createServer();

// Attach socketcluster-server to our httpServer
var scServer = socketClusterServer.attach(httpServer);

scServer.on('connection', onConnect);

function onConnect(socket){
    function onDisconnect(cb){
        console.error('Device Disconnected with socket id : ' + socket.id);
    }
    console.log('Device connected with socket id : ' + socket.id);
    socket.on('disconnect', onDisconnect);
}

httpServer.listen(8000);
console.log("STARTED");
jondubois commented 6 years ago

@skarahoda The socketcluster-client will emit an error every time it tries but fails to reconnect - This is intended behaviour, if you don't want the error to be uncaught, you need to handle it by listening to the 'error' event on the socket object and then maybe logging it somewhere?

These are more exceptions than errors. Such exceptions are a normal part of running SC; you don't necessarily need to do anything about them but it's good to log them because they tell you a story about what is happening.