From 1eba7359d1248fd77aebbc8d957602a7bdc1d4a2 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Fri, 10 Feb 2023 23:41:04 +0100 Subject: [PATCH] rolled back some changes to stabilize WebRTC connections --- index.js | 3 +- public/scripts/network.js | 46 ++++++++++++------- public/service-worker.js | 2 +- .../scripts/network.js | 46 ++++++++++++------- public_included_ws_fallback/service-worker.js | 2 +- 5 files changed, 61 insertions(+), 38 deletions(-) diff --git a/index.js b/index.js index c0ab805..136129b 100644 --- a/index.js +++ b/index.js @@ -105,7 +105,6 @@ class PairDropServer { this._joinRoom(peer); peer.socket.on('message', message => this._onMessage(peer, message)); peer.socket.onerror = e => console.error(e); - peer.socket.onclose = _ => this._onDisconnect(peer); this._keepAlive(peer); // send displayName @@ -409,7 +408,7 @@ class PairDropServer { _keepAlive(peer) { this._cancelKeepAlive(peer); - let timeout = 30000; + let timeout = 500; if (!peer.lastBeat) { peer.lastBeat = Date.now(); } diff --git a/public/scripts/network.js b/public/scripts/network.js index fdc4aa0..11197cd 100644 --- a/public/scripts/network.js +++ b/public/scripts/network.js @@ -7,6 +7,7 @@ class ServerConnection { constructor() { this._connect(); + Events.on('beforeunload', _ => this._disconnect()); Events.on('pagehide', _ => this._disconnect()); document.addEventListener('visibilitychange', _ => this._onVisibilityChange()); if (navigator.connection) navigator.connection.addEventListener('change', _ => this._reconnect()); @@ -516,11 +517,13 @@ class RTCPeer extends Peer { } _openChannel() { + if (!this._conn) return; const channel = this._conn.createDataChannel('data-channel', { ordered: true, reliable: true // Obsolete. See https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/reliable }); channel.onopen = e => this._onChannelOpened(e); + channel.onerror = e => this._onError(e); this._conn.createOffer().then(d => this._onDescription(d)).catch(e => this._onError(e)); } @@ -542,12 +545,15 @@ class RTCPeer extends Peer { if (message.sdp) { this._conn.setRemoteDescription(message.sdp) .then( _ => { - return this._conn.createAnswer() - .then(d => this._onDescription(d)); + if (message.sdp.type === 'offer') { + return this._conn.createAnswer() + .then(d => this._onDescription(d)); + } }) .catch(e => this._onError(e)); } else if (message.ice) { - this._conn.addIceCandidate(new RTCIceCandidate(message.ice)); + this._conn.addIceCandidate(new RTCIceCandidate(message.ice)) + .catch(e => this._onError(e)); } } @@ -558,15 +564,27 @@ class RTCPeer extends Peer { channel.binaryType = 'arraybuffer'; channel.onmessage = e => this._onMessage(e.data); channel.onclose = _ => this._onChannelClosed(); - Events.on('pagehide', _ => this._conn.close()); + Events.on('beforeunload', e => this._onBeforeUnload(e)); + Events.on('pagehide', _ => this._closeChannel()); this._channel = channel; } + _onBeforeUnload(e) { + if (this._busy) { + e.preventDefault(); + return "There are unfinished transfers. Are you sure you want to close?"; + } + } + + _closeChannel() { + if (this._channel) this._channel.onclose = null; + if (this._conn) this._conn.close(); + this._conn = null; + } + _onChannelClosed() { console.log('RTC: channel closed', this._peerId); Events.fire('peer-disconnected', this._peerId); - if (this._channel) this._channel.onclose = null; - this._conn.close(); if (!this._isCaller) return; this._connect(this._peerId, true); // reopen the channel } @@ -637,16 +655,6 @@ class PeersManager { Events.on('send-text', e => this._onSendText(e.detail)); Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail)); Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); - Events.on('beforeunload', e => this._onBeforeUnload(e)); - } - - _onBeforeUnload(e) { - for (const peerId in this.peers) { - if (this.peers[peerId]._busy) { - e.preventDefault(); - return "There are unfinished transfers. Are you sure you want to close?"; - } - } } _onMessage(message) { @@ -701,13 +709,17 @@ class PeersManager { _onPeerDisconnected(peerId) { const peer = this.peers[peerId]; delete this.peers[peerId]; + if (!peer || !peer._conn) return; + if (peer._channel) peer._channel.onclose = null; + peer._conn.close(); + peer._busy = false; } _onSecretRoomDeleted(roomSecret) { for (const peerId in this.peers) { const peer = this.peers[peerId]; if (peer._roomSecret === roomSecret) { - this._onPeerLeft(peerId); + this._onPeerDisconnected(peerId); } } } diff --git a/public/service-worker.js b/public/service-worker.js index 4949c4f..cbdb1a9 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,4 +1,4 @@ -const cacheVersion = 'v9'; +const cacheVersion = 'v10'; const cacheTitle = `pairdrop-cache-${cacheVersion}`; const urlsToCache = [ 'index.html', diff --git a/public_included_ws_fallback/scripts/network.js b/public_included_ws_fallback/scripts/network.js index 740870d..c6f9a85 100644 --- a/public_included_ws_fallback/scripts/network.js +++ b/public_included_ws_fallback/scripts/network.js @@ -5,6 +5,7 @@ class ServerConnection { constructor() { this._connect(); + Events.on('beforeunload', _ => this._disconnect()); Events.on('pagehide', _ => this._disconnect()); document.addEventListener('visibilitychange', _ => this._onVisibilityChange()); if (navigator.connection) navigator.connection.addEventListener('change', _ => this._reconnect()); @@ -526,11 +527,13 @@ class RTCPeer extends Peer { } _openChannel() { + if (!this._conn) return; const channel = this._conn.createDataChannel('data-channel', { ordered: true, reliable: true // Obsolete. See https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/reliable }); channel.onopen = e => this._onChannelOpened(e); + channel.onerror = e => this._onError(e); this._conn.createOffer().then(d => this._onDescription(d)).catch(e => this._onError(e)); } @@ -552,12 +555,15 @@ class RTCPeer extends Peer { if (message.sdp) { this._conn.setRemoteDescription(message.sdp) .then( _ => { - return this._conn.createAnswer() - .then(d => this._onDescription(d)); + if (message.sdp.type === 'offer') { + return this._conn.createAnswer() + .then(d => this._onDescription(d)); + } }) .catch(e => this._onError(e)); } else if (message.ice) { - this._conn.addIceCandidate(new RTCIceCandidate(message.ice)); + this._conn.addIceCandidate(new RTCIceCandidate(message.ice)) + .catch(e => this._onError(e)); } } @@ -568,15 +574,27 @@ class RTCPeer extends Peer { channel.binaryType = 'arraybuffer'; channel.onmessage = e => this._onMessage(e.data); channel.onclose = _ => this._onChannelClosed(); - Events.on('pagehide', _ => this._conn.close()); + Events.on('beforeunload', e => this._onBeforeUnload(e)); + Events.on('pagehide', _ => this._closeChannel()); this._channel = channel; } + _onBeforeUnload(e) { + if (this._busy) { + e.preventDefault(); + return "There are unfinished transfers. Are you sure you want to close?"; + } + } + + _closeChannel() { + if (this._channel) this._channel.onclose = null; + if (this._conn) this._conn.close(); + this._conn = null; + } + _onChannelClosed() { console.log('RTC: channel closed', this._peerId); Events.fire('peer-disconnected', this._peerId); - if (this._channel) this._channel.onclose = null; - this._conn.close(); if (!this._isCaller) return; this._connect(this._peerId, true); // reopen the channel } @@ -682,19 +700,9 @@ class PeersManager { Events.on('peer-left', e => this._onPeerLeft(e.detail)); Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail)); Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); - Events.on('beforeunload', e => this._onBeforeUnload(e)); Events.on('ws-relay', e => this._onWsRelay(e.detail)); } - _onBeforeUnload(e) { - for (const peerId in this.peers) { - if (this.peers[peerId]._busy) { - e.preventDefault(); - return "There are unfinished transfers. Are you sure you want to close?"; - } - } - } - _onMessage(message) { // if different roomType -> abort if (this.peers[message.sender.id] && this.peers[message.sender.id]._roomType !== message.roomType) return; @@ -761,6 +769,10 @@ class PeersManager { _onPeerDisconnected(peerId) { const peer = this.peers[peerId]; delete this.peers[peerId]; + if (!peer || !peer._conn) return; + if (peer._channel) peer._channel.onclose = null; + peer._conn.close(); + peer._busy = false; } _onPeerLeft(peerId) { @@ -774,7 +786,7 @@ class PeersManager { for (const peerId in this.peers) { const peer = this.peers[peerId]; if (peer._roomSecret === roomSecret) { - this._onPeerLeft(peerId); + this._onPeerDisconnected(peerId); } } } diff --git a/public_included_ws_fallback/service-worker.js b/public_included_ws_fallback/service-worker.js index c0364d0..5d6e718 100644 --- a/public_included_ws_fallback/service-worker.js +++ b/public_included_ws_fallback/service-worker.js @@ -1,4 +1,4 @@ -const cacheVersion = 'v9'; +const cacheVersion = 'v10'; const cacheTitle = `pairdrop-included-ws-fallback-cache-${cacheVersion}`; const urlsToCache = [ 'index.html',