From 7746ca17008518e04bced57f7c3b1b11eca4b408 Mon Sep 17 00:00:00 2001 From: Darren Date: Thu, 3 Jul 2014 23:13:31 +0100 Subject: [PATCH] Reconnecting when IRCd drops the connection --- client/src/views/serverselect.js | 6 ++++++ server/irc/connection.js | 29 ++++++++++++++++++++++++++++- server/irc/server.js | 11 +++++++++++ server/irc/state.js | 4 ++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/client/src/views/serverselect.js b/client/src/views/serverselect.js index 054aad0..025a1a2 100644 --- a/client/src/views/serverselect.js +++ b/client/src/views/serverselect.js @@ -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'); diff --git a/server/irc/connection.js b/server/irc/connection.js index f6ac97a..69eb684 100644 --- a/server/irc/connection.js +++ b/server/irc/connection.js @@ -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); } diff --git a/server/irc/server.js b/server/irc/server.js index 2e42fab..2dec789 100755 --- a/server/irc/server.js +++ b/server/irc/server.js @@ -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 }); diff --git a/server/irc/state.js b/server/irc/state.js index 92bc35b..9ae2df0 100755 --- a/server/irc/state.js +++ b/server/irc/state.js @@ -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'}); -- 2.25.1