Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reconnect logic may get in endless loop #180

Closed
kriskep opened this issue May 8, 2014 · 3 comments · Fixed by #183
Closed

reconnect logic may get in endless loop #180

kriskep opened this issue May 8, 2014 · 3 comments · Fixed by #183

Comments

@kriskep
Copy link
Contributor

kriskep commented May 8, 2014

It is possible that the reconnection procedure may get in an endless loop of close and connect events.

The code below reproduces the problem on Ubuntu 12.04 with default mosquitto installation. Note I had to use iptables to simulate bad network conditions.

var mqtt = require('mqtt');

var host = '127.0.0.1';
var port = 1883;
var args = {
     keepalive: 10,
     reconnectPeriod: 6000
};

var LOG = function(m) {
    console.log(new Date().toLocaleString() + ': ' + m);
}

var mqttclient = mqtt.createClient(port, host, args);

mqttclient.on('connect', function() {
    LOG('mqtt client connected');
});

mqttclient.on('disconnect', function() {
    console.log('mqtt client disconnected');
});

mqttclient.on('error', function(err) {
    LOG('mqtt client error:');
        LOG(err);
});

mqttclient.on('close', function(err) {
    LOG('mqtt client closed');
});

setTimeout(function() {
    var exec = require('child_process').exec;
    exec('sudo iptables -A INPUT -p tcp --dport 1883 -j DROP', function(error) {
        if (error !== null) {
            LOG('error configuring iptables '+error);
        } else {
            LOG('iptables drop 1883');
            setTimeout(function() {
                exec('sudo iptables -D INPUT -p tcp --dport 1883 -j DROP', function(err) {
                    if (error !== null) {
                        LOG('error configuring iptables '+error);
                    } else {
                        LOG('iptables accept 1883');
                    }
                } );
            }, 15000 );
        }
    } );
}, 10000 );


setInterval(function() {
    mqttclient.publish('/test/ping', 'testmsg');
}, 1000 );
@kriskep
Copy link
Contributor Author

kriskep commented May 9, 2014

I digged a bit further and the problem is the following:

  1. ping response fails and a close event is generated. Socket.end() is called. reconnect timer is started. (reconnectPeriod)
  2. after reconnectPeriod, reconnection attempt is made
  3. a close event is generated for the socket.end() in 1. reconnectTimer is started again
  4. network connection is restored
  5. reconnection succeeds and connect is sent
  6. reconnectTimer from step 3 expires, and a new reconnection attempt is made(!)
  7. mosquitto detects 2 connections for the same clientId and closes one of them
    etc ....

@kriskep
Copy link
Contributor Author

kriskep commented May 9, 2014

kriskep@2e662a8 fixes this problem

@mikelfo
Copy link

mikelfo commented May 9, 2014

Thank you, I was also experiencing this issue!

kriskep referenced this issue in kriskep/MQTT.js May 9, 2014
* do not generate 'close' event on ping failure - rely on socket 'close' event instead
* destroy() socket instead end() to make sure 'close' event comes quickly
@mcollina mcollina mentioned this issue May 10, 2014
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants