Skip to content

Commit 617f937

Browse files
committed
Fixes for websocket reconnecting.
Fix bug where some network failures during connect would abort the retry loop and leave the message receiver abandonded.
1 parent 6b696ed commit 617f937

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

src/message_receiver.js

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const libsignal = require('libsignal');
1111
const protobufs = require('./protobufs');
1212
const queueAsync = require('./queue_async');
1313
const storage = require('./storage');
14-
const util = require('./util');
1514

1615

1716
const ENV_TYPES = protobufs.Envelope.lookup('Type').values;
@@ -53,7 +52,26 @@ class MessageReceiver extends eventing.EventTarget {
5352
if (this._closing) {
5453
throw new Error("Invalid State: Already Closed");
5554
}
56-
await this.wsr.connect();
55+
if (this._connecting) {
56+
console.warn("Duplicate connect detected");
57+
} else {
58+
this._connecting = (async () => {
59+
let attempts = 0;
60+
while (!this._closing) {
61+
try {
62+
await this.wsr.connect();
63+
if (attempts) {
64+
console.info("Reconnected websocket");
65+
}
66+
return;
67+
} catch(e) {
68+
console.warn(`Connect problem (${attempts++} attempts):`, e);
69+
}
70+
}
71+
})();
72+
}
73+
await this._connecting;
74+
this._connecting = null;
5775
}
5876

5977
close() {
@@ -89,35 +107,26 @@ class MessageReceiver extends eventing.EventTarget {
89107
} while(more);
90108
}
91109

92-
onSocketError(error) {
93-
console.error('Message Receiver - WebSocket error:', error);
94-
throw error;
110+
onSocketError(ev) {
111+
console.warn('Message Receiver WebSocket error:', ev);
95112
}
96113

97114
async onSocketClose(ev) {
98-
console.warn('Websocket closed:', ev.code, ev.reason || '');
99-
if (ev.code === 3000 || this._closing) {
115+
if (this._closing) {
100116
return;
101117
}
102-
// possible auth or network issue. Make a request to confirm
103-
let attempt = 0;
104-
while (!this._closing) {
105-
try {
106-
await this.signal.getDevices();
107-
break;
108-
} catch(e) {
109-
const backoff = Math.log1p(++attempt) * 30 * Math.random();
110-
console.error("Invalid network state:", e);
111-
const errorEvent = new eventing.Event('error');
112-
errorEvent.error = e;
113-
await this.dispatchEvent(errorEvent);
114-
console.info(`Will retry network in ${backoff} seconds (attempt ${attempt}).`);
115-
await util.sleep(backoff);
116-
}
117-
}
118-
if (!this._closing) {
119-
await this.connect();
118+
console.warn('Websocket closed:', ev.code, ev.reason || '');
119+
try {
120+
// possible auth or network issue. Make a request to confirm
121+
await this.signal.getDevices();
122+
} catch(e) {
123+
// TODO: Catch auth error and unregister here?
124+
console.error("Invalid network state:", e);
125+
const errorEvent = new eventing.Event('error');
126+
errorEvent.error = e;
127+
await this.dispatchEvent(errorEvent);
120128
}
129+
await this.connect();
121130
}
122131

123132
async handleRequest(request) {

src/websocket_resource.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ class WebSocketResource {
152152
this._connectCount++;
153153
if (this._lastDuration && this._lastDuration < 10000) {
154154
const delay = Math.max(5, Math.random() * this._connectCount);
155-
console.warn('Throttling websocket reconnect:', delay);
155+
console.warn(`Throttling websocket reconnect for ${Math.round(delay)} seconds.`);
156156
await util.sleep(delay);
157157
}
158158
const ws = new WebSocket(this.url);

0 commit comments

Comments
 (0)