Reconnecting when IRCd drops the connection
authorDarren <darren@darrenwhitlen.com>
Thu, 3 Jul 2014 22:13:31 +0000 (23:13 +0100)
committerDarren <darren@darrenwhitlen.com>
Thu, 3 Jul 2014 22:13:31 +0000 (23:13 +0100)
client/src/views/serverselect.js
server/irc/connection.js
server/irc/server.js
server/irc/state.js

index 054aad0c596a26e11ea3373cb3b0c05cd9314171..025a1a2d59ddc9b3e08bd9e02f60c045a30e41d4 100644 (file)
@@ -46,6 +46,7 @@ _kiwi.view.ServerSelect = Backbone.View.extend({
         this.gateway = _kiwi.global.components.Network();
         this.gateway.on('connect', this.networkConnected, this);
         this.gateway.on('connecting', this.networkConnecting, this);
+        this.gateway.on('disconnect', this.networkDisconnected, this);
         this.gateway.on('irc_error', this.onIrcError, this);
     },
 
@@ -258,6 +259,11 @@ _kiwi.view.ServerSelect = Backbone.View.extend({
         this.model.current_connecting_network = null;
     },
 
+    networkDisconnected: function () {
+        this.model.current_connecting_network = null;
+        this.state = 'all';
+    },
+
     networkConnecting: function (event) {
         this.model.trigger('connecting');
         this.setStatus(_kiwi.global.i18n.translate('client_views_serverselect_connection_trying').fetch(), 'ok');
index f6ac97aa3a55f165166fce0a3589756167342516..69eb6847f834db6ef6f047e41599a60d1f46b85e 100644 (file)
@@ -37,6 +37,9 @@ var IrcConnection = function (hostname, port, ssl, nick, user, options, state, c
     // Socket state
     this.connected = false;
 
+    // If the connection closes and this is false, we reconnect
+    this.requested_disconnect = false;
+
     // IRCd write buffers (flood controll)
     this.write_buffer = [];
 
@@ -175,6 +178,8 @@ IrcConnection.prototype.connect = function () {
     // Make sure we don't already have an open connection
     this.disposeSocket();
 
+    this.requested_disconnect = false;
+
     // Get the IP family for the dest_addr (either socks or IRCd destination)
     getConnectionFamily(dest_addr, function getConnectionFamilyCb(err, family, host) {
         var outgoing;
@@ -290,17 +295,37 @@ IrcConnection.prototype.connect = function () {
         });
 
         that.socket.on('close', function socketCloseCb(had_error) {
+            // If that.connected is false, we never actually managed to connect
+            var was_connected = that.connected,
+                had_registered = that.server.registered,
+                should_reconnect = false;
+
             that.connected = false;
+            that.server.reset();
 
             // Remove this socket form the identd lookup
             if (that.identd_port_pair) {
                 delete global.clients.port_pairs[that.identd_port_pair];
             }
 
-            that.emit('close', had_error);
+            should_reconnect = (!that.requested_disconnect && was_connected && had_registered);
+
+            if (should_reconnect) {
+                that.emit('reconnecting');
+            } else {
+                that.emit('close', had_error);
+            }
 
             // Close the whole socket down
             that.disposeSocket();
+
+            // If this socket closing was not expected and we did actually connect and
+            // we did previously completely register on the network, then reconnect
+            if (should_reconnect) {
+                setTimeout(function() {
+                    that.connect();
+                }, 3000);
+            }
         });
     });
 };
@@ -392,6 +417,8 @@ IrcConnection.prototype.end = function (data) {
         return;
     }
 
+    this.requested_disconnect = true;
+
     if (data) {
         this.write(data, true);
     }
index 2e42fab6730c9dadee29365e87ab8d0c6b57a1a7..2dec7899c413e291779163c14e252aab8cc11611 100755 (executable)
@@ -8,6 +8,8 @@ var IrcServer = function (irc_connection) {
     this.list_buffer = [];
     this.motd_buffer = '';
 
+    this.registered = false;
+
     this.irc_events = {
         connect:                onConnect,
         options:                onOptions,
@@ -49,8 +51,17 @@ IrcServer.prototype.dispose = function (){
 };
 
 
+IrcServer.prototype.reset = function() {
+    this.registered = false;
+    this.list_buffer = [];
+    this.motd_buffer = '';
+};
+
+
 
 function onConnect(event) {
+    this.registered = true;
+
     this.irc_connection.clientEvent('connect', {
         nick: event.nick
     });
index 92bc35be5550b06face35b98abefc79718927060..9ae2df031ff0cc3e251013eda573e3f14f7804a2 100755 (executable)
@@ -70,6 +70,10 @@ State.prototype.connect = function (hostname, port, ssl, nick, user, options, ca
         return callback(err.message);
     });
 
+    con.on('reconnecting', function IrcConnectionReconnecting() {
+        that.sendIrcCommand('disconnect', {connection_id: con.con_num, reason: 'IRC server reconnecting'});
+    });
+
     con.on('close', function IrcConnectionClose() {
         // TODO: Can we get a better reason for the disconnection? Was it planned?
         that.sendIrcCommand('disconnect', {connection_id: con.con_num, reason: 'disconnected'});