diff options
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/transport.js | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js index 0b796cab..11088adc 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js @@ -747,6 +747,9 @@ class MeshBayTransport { // and a single setter meant the second to arrive silently replaced // the first, then cleared it on the way out. this._reconnectListeners = new Set(); + // Told of each attempt that failed, with its error: a reconnect refused + // the local network tries again for ever and says nothing otherwise. + this._reconnectFailureListeners = new Set(); this._onNeedToken = null; // Which device key THIS connection has identified itself to the node with. // Empty means "not identified": nothing can be sealed, so nothing can be @@ -762,6 +765,9 @@ class MeshBayTransport { // connect() like the diagnostic listener above it — this one has to // survive every reconnect attempt, not restart with each one. this._reconnectWakeResolve = null; + // Set by retryNow for the attempt it gave up: the next waits for nothing. + this._retryAtOnce = false; + this._abandonAttempt = null; this._onVisibilityWake = () => { if (document.visibilityState === 'visible') this._wakeReconnect(); }; @@ -823,6 +829,21 @@ class MeshBayTransport { } } + /** + * Tries again now: the person has just changed what made it fail. An + * attempt under way set up its connection before that change (a permission + * granted), and Chrome keeps refusing the addresses it dropped then until + * ICE gives up, half a minute: it is given up here, and the next starts at + * once. + */ + retryNow() { + if (this._inReconnectAttempt && this._abandonAttempt) { + this._retryAtOnce = true; + this._abandonAttempt(); + } + this._wakeReconnect(); + } + get connected() { return this._connected; } /** True while _reconnectLoop is running, backoff included. */ get reconnecting() { return !!this._reconnectPromise; } @@ -864,6 +885,17 @@ class MeshBayTransport { } /** + * Told of each automatic reconnect attempt that failed, with its error, while + * the reconnect goes on. A phone that leaves mobile data for the node's Wi-Fi + * without the local network permission is refused on every attempt + * (`reason` local_network_blocked), and only the page can say why. + */ + addReconnectFailureListener(fn) { + this._reconnectFailureListeners.add(fn); + return () => this._reconnectFailureListeners.delete(fn); + } + + /** * Told whenever this connection's device identity changes — including to * *nothing*, which is the case that mattered. * @@ -1007,6 +1039,8 @@ class MeshBayTransport { // DataChannel closed" on the console. Every failed reconnect attempt // printed one, which is noise in exactly the log a freeze gets read from. channelReady.catch(() => { /* the awaiter below reports it */ }); + // retryNow; a no-op once the channel is open. + this._abandonAttempt = () => channelReject(new Error('Tried again at once')); this._channel.onmessage = (event) => this._onMessage(event.data); const channel = this._channel; @@ -1698,7 +1732,9 @@ class MeshBayTransport { this._reconnectAttempts = 0; while (!this._closed) { this._reconnectAttempts += 1; - const delayMs = Math.min(30000, 1000 * 2 ** (this._reconnectAttempts - 1)); + const delayMs = this._retryAtOnce ? 0 + : Math.min(30000, 1000 * 2 ** (this._reconnectAttempts - 1)); + this._retryAtOnce = false; trace('reconnect_wait', { attempt: this._reconnectAttempts, delay_ms: delayMs }); // Interruptible: _wakeReconnect (fired on visibilitychange → visible) // resolves this immediately instead of waiting out the rest of a @@ -1752,6 +1788,11 @@ class MeshBayTransport { }); console.warn('[MeshBay] Reconnect attempt', this._reconnectAttempts, 'failed:', e.message); + for (const fn of [...this._reconnectFailureListeners]) { + try { fn(e); } catch (err) { + console.error('[MeshBay] reconnect failure listener threw:', err); + } + } // Loop again with a longer backoff — closing over `args`/`token` // freshly next time, in case the token was the actual problem. } |