SailsSocket Keep Trying to Reconnect

2019-07-26 20:22发布

问题:

After struggling with socket.io connection authentication (here and here) and thanks to @sgress454, I realized how to get this to work and I am sending the authentication/authorization token as part of the query in the connection (see below).

Upon authentication failure (invalid/expired token or in-active user), I return the callback with false parameter to indicate the connection is rejected.

On the client side though, I am not sure how I should handled it and it seems the socket is trying to reconnect even after explicitly disconnecting - I keep seeing that it is trying to reconnect.

The client code is something like this:

var _onConnectError = function(err) {
    if (err.description == 400) {
        console.log("Connection rejected");
        _disconnectAndCleanupSocket();
    } else {
        console.log("##SOCKET - connect_error", err.description, err);
    }
}

var _disconnectAndCleanupSocket = function() {
    if (io.socket) {
        if (io.socket.isConnected()) {
            io.socket.disconnect();
        }

        io.socket.removeAllListeners();
        delete io.socket;
    }
};

io.socket = io.sails.connect({ query: "token=" + token});
io.socket.on('connect', _onConnect);
io.socket.on('connect_error', _onConnectError);
io.socket.on('reconnect_error', _onConnectError);

On the server (config/sockets.js) I have:

beforeConnect: function(handshake, cb) {
    var token = handshake._query ? handshake._query.token : null;

    CipherService.verifyToken(token, function verifyTokenResults(err, decoded, info) {
        if (err || !decoded) {
            if (err.name === "TokenExpiredError") {
                // token expired - user can't connect...
                return cb(null, false);
            } else {
                // some other error...
                return cb(err, false);
            }
        }

        AuthUser.findOne(decoded.user.id).exec(function(err, user) {
            if (err || !user || !user.is_active) {
                return cb(null, false);
            }

            return cb(null, true);
        });
    });
    // (`false` would reject the connection)
},

I have tried to find documentation and explored the response object (in developer tools) but the only thing I saw there was thedescription field which return 400 on rejection and 0 in case there is no response (e.g. server is down).

Is there some example/documentation for this? Overall, I didn't find detailed description of using the SailsSocket in non-standard cases (other then use io.sails.connect()).

What is the proper way to handle such rejection (and shouldn't it handle it as part of the sails socket.io client?)

As an aside, I cannot instantiate SailsSocket myself and only do this with the 'io.sails.connect()' function. Is that on purpose? Is there no option to "miss" an event when I create the socket with the connect method and only then assign event handlers?

回答1:

The short answer to your question is that you can set the reconnection flag to turn automatic reconnection on or off:

// Disable auto-reconnect for all new socket connections
io.sails.reconnection = false;

// Disable auto-reconnect for a single new socket connection
var mySocket = io.sails.connect({reconnection: false});

As far as SailsSocket creation, you are correct in that io.sails.connect() is the only way to create a SailsSocket. Since the connection is asynchronous, any event handlers you bind immediately after calling connect will be added before the actual connection takes place, so you won't miss any notifications.