Merge pull request #477 from glowing-bear/reconnect
[WIP] Start implementing auto-reconnect
This commit is contained in:
commit
afdcaadb72
6 changed files with 148 additions and 17 deletions
|
@ -263,6 +263,19 @@ td.time {
|
|||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#reconnect {
|
||||
top: 35px;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
width: 80%;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
left: 10%;
|
||||
}
|
||||
#reconnect a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
|
|
|
@ -295,6 +295,11 @@ $ openssl req -nodes -newkey rsa:4096 -keyout relay.pem -x509 -days 365 -out rel
|
|||
</div>
|
||||
</div>
|
||||
<div id="soundNotification"></div>
|
||||
<div id="reconnect" class="alert alert-danger" ng-click="reconnect()" ng-show="reconnecting">
|
||||
<p><strong>Connection to WeeChat lost</strong></p>
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
Reconnecting... <a class="btn btn-tiny" ng-click="reconnect()">Click to try to reconnect now</a>
|
||||
</div>
|
||||
<div id="settingsModal" class="gb-modal" data-state="hidden">
|
||||
<div class="backdrop" ng-click="closeModal($event)"></div>
|
||||
<div class="modal-dialog">
|
||||
|
|
|
@ -12,9 +12,12 @@ weechat.factory('connection',
|
|||
|
||||
var protocol = new weeChat.Protocol();
|
||||
|
||||
// Takes care of the connection and websocket hooks
|
||||
var connectionData = [];
|
||||
var reconnectTimer;
|
||||
|
||||
var connect = function (host, port, passwd, ssl, noCompression) {
|
||||
// Takes care of the connection and websocket hooks
|
||||
var connect = function (host, port, passwd, ssl, noCompression, successCallback, failCallback) {
|
||||
connectionData = [host, port, passwd, ssl, noCompression];
|
||||
var proto = ssl ? 'wss' : 'ws';
|
||||
// If host is an IPv6 literal wrap it in brackets
|
||||
if (host.indexOf(":") !== -1) {
|
||||
|
@ -79,21 +82,15 @@ weechat.factory('connection',
|
|||
// Connection is successful
|
||||
// Send all the other commands required for initialization
|
||||
_requestBufferInfos().then(function(bufinfo) {
|
||||
//XXX move to handlers?
|
||||
var bufferInfos = bufinfo.objects[0].content;
|
||||
// buffers objects
|
||||
for (var i = 0; i < bufferInfos.length ; i++) {
|
||||
var buffer = new models.Buffer(bufferInfos[i]);
|
||||
models.addBuffer(buffer);
|
||||
// Switch to first buffer on startup
|
||||
if (i === 0) {
|
||||
models.setActiveBuffer(buffer.id);
|
||||
}
|
||||
}
|
||||
handlers.handleBufferInfo(bufinfo);
|
||||
});
|
||||
|
||||
_requestHotlist().then(function(hotlist) {
|
||||
handlers.handleHotlistInfo(hotlist);
|
||||
|
||||
if (successCallback) {
|
||||
successCallback();
|
||||
}
|
||||
});
|
||||
|
||||
_requestSync();
|
||||
|
@ -123,10 +120,19 @@ weechat.factory('connection',
|
|||
* Handles websocket disconnection
|
||||
*/
|
||||
$log.info("Disconnected from relay");
|
||||
if ($rootScope.userdisconnect || !$rootScope.waseverconnected) {
|
||||
handleClose(evt);
|
||||
$rootScope.userdisconnect = false;
|
||||
} else {
|
||||
reconnect(evt);
|
||||
}
|
||||
};
|
||||
|
||||
var handleClose = function (evt) {
|
||||
ngWebsockets.failCallbacks('disconnection');
|
||||
$rootScope.connected = false;
|
||||
$rootScope.$emit('relayDisconnect');
|
||||
if (ssl && evt.code === 1006) {
|
||||
if (ssl && evt && evt.code === 1006) {
|
||||
// A password error doesn't trigger onerror, but certificate issues do. Check time of last error.
|
||||
if (typeof $rootScope.lastError !== "undefined" && (Date.now() - $rootScope.lastError) < 1000) {
|
||||
// abnormal disconnect by client, most likely ssl error
|
||||
|
@ -166,11 +172,64 @@ weechat.factory('connection',
|
|||
$rootScope.errorMessage = true;
|
||||
$rootScope.securityError = true;
|
||||
$rootScope.$emit('relayDisconnect');
|
||||
|
||||
if (failCallback) {
|
||||
failCallback();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var attemptReconnect = function (bufferId, timeout) {
|
||||
$log.info('Attempting to reconnect...');
|
||||
var d = connectionData;
|
||||
connect(d[0], d[1], d[2], d[3], d[4], function() {
|
||||
$rootScope.reconnecting = false;
|
||||
// on success, update active buffer
|
||||
models.setActiveBuffer(bufferId);
|
||||
$log.info('Sucessfully reconnected to relay');
|
||||
}, function() {
|
||||
// on failure, schedule another attempt
|
||||
if (timeout >= 600000) {
|
||||
// If timeout is ten minutes or more, give up
|
||||
$log.info('Failed to reconnect, giving up');
|
||||
handleClose();
|
||||
} else {
|
||||
$log.info('Failed to reconnect, scheduling next attempt in', timeout/1000, 'seconds');
|
||||
// Clear previous timer, if exists
|
||||
if (reconnectTimer !== undefined) {
|
||||
clearTimeout(reconnectTimer);
|
||||
}
|
||||
reconnectTimer = setTimeout(function() {
|
||||
// exponential timeout increase
|
||||
attemptReconnect(bufferId, timeout * 1.5);
|
||||
}, timeout);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var reconnect = function (evt) {
|
||||
if (connectionData.length < 5) {
|
||||
// something is wrong
|
||||
$log.error('Cannot reconnect, connection information is missing');
|
||||
return;
|
||||
}
|
||||
|
||||
$rootScope.reconnecting = true;
|
||||
// Have to do this to get the reconnect banner to show
|
||||
$rootScope.$apply();
|
||||
|
||||
var bufferId = models.getActiveBuffer().id,
|
||||
timeout = 3000; // start with a three-second timeout
|
||||
|
||||
reconnectTimer = setTimeout(function() {
|
||||
attemptReconnect(bufferId, timeout);
|
||||
}, timeout);
|
||||
};
|
||||
|
||||
var disconnect = function() {
|
||||
$rootScope.userdisconnect = true;
|
||||
ngWebsockets.send(weeChat.Protocol.formatQuit());
|
||||
};
|
||||
|
||||
|
@ -270,7 +329,8 @@ weechat.factory('connection',
|
|||
sendMessage: sendMessage,
|
||||
sendCoreCommand: sendCoreCommand,
|
||||
fetchMoreLines: fetchMoreLines,
|
||||
requestNicklist: requestNicklist
|
||||
requestNicklist: requestNicklist,
|
||||
attemptReconnect: attemptReconnect
|
||||
};
|
||||
}]);
|
||||
})();
|
||||
|
|
|
@ -264,6 +264,8 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
|
|||
|
||||
$rootScope.connected = false;
|
||||
$rootScope.waseverconnected = false;
|
||||
$rootScope.userdisconnect = false;
|
||||
$rootScope.reconnecting = false;
|
||||
|
||||
$rootScope.models = models;
|
||||
|
||||
|
@ -513,6 +515,10 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
|
|||
$scope.connectbutton = 'Connect';
|
||||
connection.disconnect();
|
||||
};
|
||||
$scope.reconnect = function() {
|
||||
var bufferId = models.getActiveBuffer().id;
|
||||
connection.attemptReconnect(bufferId, 3000);
|
||||
};
|
||||
|
||||
//XXX this is a bit out of place here, either move up to the rest of the firefox install code or remove
|
||||
$scope.install = function() {
|
||||
|
|
|
@ -43,6 +43,53 @@ weechat.factory('handlers', ['$rootScope', '$log', 'models', 'plugins', 'notific
|
|||
}
|
||||
};
|
||||
|
||||
var handleBufferInfo = function(message) {
|
||||
var bufferInfos = message.objects[0].content;
|
||||
// buffers objects
|
||||
for (var i = 0; i < bufferInfos.length ; i++) {
|
||||
var bufferId = bufferInfos[i].pointers[0];
|
||||
var buffer = models.getBuffer(bufferId);
|
||||
if (buffer !== undefined) {
|
||||
// We already know this buffer
|
||||
handleBufferUpdate(buffer, bufferInfos[i]);
|
||||
} else {
|
||||
buffer = new models.Buffer(bufferInfos[i]);
|
||||
models.addBuffer(buffer);
|
||||
// Switch to first buffer on startup
|
||||
if (i === 0) {
|
||||
models.setActiveBuffer(buffer.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var handleBufferUpdate = function(buffer, message) {
|
||||
if (message.pointers[0] !== buffer.id) {
|
||||
// this is information about some other buffer!
|
||||
return;
|
||||
}
|
||||
|
||||
// weechat properties -- short name can be changed
|
||||
buffer.shortName = message.short_name;
|
||||
buffer.trimmedName = buffer.shortName.replace(/^[#&+]/, '');
|
||||
buffer.title = message.title;
|
||||
buffer.number = message.number;
|
||||
|
||||
// reset these, hotlist info will arrive shortly
|
||||
buffer.notification = 0;
|
||||
buffer.unread = 0;
|
||||
buffer.lastSeen = -1;
|
||||
|
||||
if (message.local_variables.type !== undefined) {
|
||||
buffer.type = message.local_variables.type;
|
||||
buffer.indent = (['channel', 'private'].indexOf(buffer.type) >= 0);
|
||||
}
|
||||
|
||||
if (message.notify !== undefined) {
|
||||
buffer.notify = message.notify;
|
||||
}
|
||||
};
|
||||
|
||||
var handleBufferLineAdded = function(message) {
|
||||
message.objects[0].content.forEach(function(l) {
|
||||
handleLine(l, false);
|
||||
|
@ -216,7 +263,8 @@ weechat.factory('handlers', ['$rootScope', '$log', 'models', 'plugins', 'notific
|
|||
handleEvent: handleEvent,
|
||||
handleLineInfo: handleLineInfo,
|
||||
handleHotlistInfo: handleHotlistInfo,
|
||||
handleNicklist: handleNicklist
|
||||
handleNicklist: handleNicklist,
|
||||
handleBufferInfo: handleBufferInfo
|
||||
};
|
||||
|
||||
}]);
|
||||
|
|
|
@ -110,7 +110,6 @@ function($rootScope, $q) {
|
|||
$rootScope.$emit('onMessage', message);
|
||||
}
|
||||
|
||||
$rootScope.$apply();
|
||||
};
|
||||
|
||||
var connect = function(url,
|
||||
|
|
Loading…
Reference in a new issue