Better handling of network disconnection/reconnection (#1546)
* Ensure that our preload.js setImmediate call finds right function FREEBIE * Our own socket close event, better logging, unregistration FREEBIE * Return CLOSED for NetworkStatusView if we've fully disconnected * background.js: Remove messageReceiver = null, log in connect() A null messageReciever makes the NetworkStatusView think we're online. FREEBIE
This commit is contained in:
parent
52cc8355a6
commit
b64f2969fd
6 changed files with 363 additions and 228 deletions
|
@ -28,8 +28,11 @@ MessageReceiver.prototype = new textsecure.EventTarget();
|
|||
MessageReceiver.prototype.extend({
|
||||
constructor: MessageReceiver,
|
||||
connect: function() {
|
||||
this.hasConnected = true;
|
||||
|
||||
if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
|
||||
this.socket.close();
|
||||
this.wsr.close();
|
||||
}
|
||||
// initialize the socket and start listening for messages
|
||||
this.socket = this.server.getMessageSocket();
|
||||
|
@ -38,16 +41,45 @@ MessageReceiver.prototype.extend({
|
|||
this.socket.onopen = this.onopen.bind(this);
|
||||
this.wsr = new WebSocketResource(this.socket, {
|
||||
handleRequest: this.handleRequest.bind(this),
|
||||
keepalive: { path: '/v1/keepalive', disconnect: true }
|
||||
keepalive: {
|
||||
path: '/v1/keepalive',
|
||||
disconnect: true
|
||||
}
|
||||
});
|
||||
|
||||
// Because sometimes the socket doesn't properly emit its close event
|
||||
this._onClose = this.onclose.bind(this)
|
||||
this.wsr.addEventListener('close', this._onClose);
|
||||
|
||||
// Ensures that an immediate 'empty' event from the websocket will fire only after
|
||||
// all cached envelopes are processed.
|
||||
this.incoming = [this.pending];
|
||||
},
|
||||
shutdown: function() {
|
||||
if (this.socket) {
|
||||
this.socket.onclose = null;
|
||||
this.socket.onerror = null;
|
||||
this.socket.onopen = null;
|
||||
this.socket = null;
|
||||
}
|
||||
|
||||
if (this.wsr) {
|
||||
this.wsr.removeEventListener('close', this._onClose);
|
||||
this.wsr = null;
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
console.log('MessageReceiver.close()');
|
||||
this.calledClose = true;
|
||||
this.socket.close(3000, 'called close');
|
||||
|
||||
// Our WebSocketResource instance will close the socket and emit a 'close' event
|
||||
// if the socket doesn't emit one quickly enough.
|
||||
if (this.wsr) {
|
||||
this.wsr.close(3000, 'called close');
|
||||
}
|
||||
|
||||
this.shutdown();
|
||||
|
||||
return this.drain();
|
||||
},
|
||||
onopen: function() {
|
||||
|
@ -68,6 +100,8 @@ MessageReceiver.prototype.extend({
|
|||
this.calledClose
|
||||
);
|
||||
|
||||
this.shutdown();
|
||||
|
||||
if (this.calledClose) {
|
||||
return;
|
||||
}
|
||||
|
@ -332,6 +366,8 @@ MessageReceiver.prototype.extend({
|
|||
getStatus: function() {
|
||||
if (this.socket) {
|
||||
return this.socket.readyState;
|
||||
} else if (this.hasConnected) {
|
||||
return WebSocket.CLOSED;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -138,22 +138,55 @@
|
|||
};
|
||||
|
||||
if (opts.keepalive) {
|
||||
var keepalive = new KeepAlive(this, {
|
||||
this.keepalive = new KeepAlive(this, {
|
||||
path : opts.keepalive.path,
|
||||
disconnect : opts.keepalive.disconnect
|
||||
});
|
||||
var resetKeepAliveTimer = keepalive.reset.bind(keepalive);
|
||||
var resetKeepAliveTimer = this.keepalive.reset.bind(this.keepalive);
|
||||
socket.addEventListener('open', resetKeepAliveTimer);
|
||||
socket.addEventListener('message', resetKeepAliveTimer);
|
||||
socket.addEventListener('close', keepalive.stop.bind(keepalive));
|
||||
socket.addEventListener('close', this.keepalive.stop.bind(this.keepalive));
|
||||
}
|
||||
|
||||
this.close = function(code, reason) {
|
||||
if (!code) { code = 3000; }
|
||||
socket.close(code, reason);
|
||||
};
|
||||
socket.addEventListener('close', function() {
|
||||
this.closed = true;
|
||||
}.bind(this))
|
||||
|
||||
this.close = function(code, reason) {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('WebSocketResource.close()');
|
||||
if (!code) {
|
||||
code = 3000;
|
||||
}
|
||||
if (this.keepalive) {
|
||||
this.keepalive.stop();
|
||||
}
|
||||
|
||||
socket.close(code, reason);
|
||||
socket.onmessage = null;
|
||||
|
||||
// On linux the socket can wait a long time to emit its close event if we've
|
||||
// lost the internet connection. On the order of minutes. This speeds that
|
||||
// process up.
|
||||
setTimeout(function() {
|
||||
if (this.closed) {
|
||||
return;
|
||||
}
|
||||
this.closed = true;
|
||||
|
||||
console.log('Dispatching our own socket close event');
|
||||
var ev = new Event('close');
|
||||
ev.code = code;
|
||||
ev.reason = reason;
|
||||
this.dispatchEvent(ev);
|
||||
}.bind(this), 10000);
|
||||
};
|
||||
};
|
||||
window.WebSocketResource.prototype = new textsecure.EventTarget();
|
||||
|
||||
|
||||
function KeepAlive(websocketResource, opts) {
|
||||
if (websocketResource instanceof WebSocketResource) {
|
||||
|
@ -182,12 +215,6 @@
|
|||
clearTimeout(this.keepAliveTimer);
|
||||
clearTimeout(this.disconnectTimer);
|
||||
this.keepAliveTimer = setTimeout(function() {
|
||||
console.log('Sending a keepalive message');
|
||||
this.wsr.sendRequest({
|
||||
verb: 'GET',
|
||||
path: this.path,
|
||||
success: this.reset.bind(this)
|
||||
});
|
||||
if (this.disconnect) {
|
||||
// automatically disconnect if server doesn't ack
|
||||
this.disconnectTimer = setTimeout(function() {
|
||||
|
@ -197,6 +224,12 @@
|
|||
} else {
|
||||
this.reset();
|
||||
}
|
||||
console.log('Sending a keepalive message');
|
||||
this.wsr.sendRequest({
|
||||
verb: 'GET',
|
||||
path: this.path,
|
||||
success: this.reset.bind(this)
|
||||
});
|
||||
}.bind(this), 55000);
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue