ソースを参照

fix(ParticipantConnStatus): get in sync with JVB status

When the remote track which caused to transit to the disconnected status
is removed from the conference the current status received through
the data channels should be used to avoid getting out of sync by missing
"muted"/"unmuted" events sequence.

Usually the track removed is replaced by the new one(in our use cases),
but the new track is always added unmuted. Now if the connection gets
restored in the meantime while the track is being signalled then
the 'muted/unmuted' event sequence may be missed and the participant
might be blocked in the "disconnected" state forever.
dev1
paweldomas 9年前
コミット
a5dd7780b1
1個のファイルの変更74行の追加1行の削除
  1. 74
    1
      modules/connectivity/ParticipantConnectionStatus.js

+ 74
- 1
modules/connectivity/ParticipantConnectionStatus.js ファイルの表示

@@ -40,6 +40,13 @@ export default class ParticipantConnectionStatus {
40 40
          * @type {Object.<string, number>}
41 41
          */
42 42
         this.trackTimers = {};
43
+        /**
44
+         * This map holds the endpoint connection status received from the JVB
45
+         * (as it might be different than the one stored in JitsiParticipant).
46
+         * Required for getting back in sync when remote video track is removed.
47
+         * @type {Object.<string, boolean>}
48
+         */
49
+        this.rtcConnStatusCache = { };
43 50
         /**
44 51
          * How long we're going to wait after the RTC video track muted event
45 52
          * for the corresponding signalling mute event, before the connection
@@ -128,6 +135,9 @@ export default class ParticipantConnectionStatus {
128 135
         Object.keys(this.trackTimers).forEach(function (participantId) {
129 136
             this.clearTimeout(participantId);
130 137
         }.bind(this));
138
+
139
+        // Clear RTC connection status cache
140
+        this.rtcConnStatusCache = {};
131 141
     }
132 142
 
133 143
     /**
@@ -145,6 +155,12 @@ export default class ParticipantConnectionStatus {
145 155
 
146 156
         // Filter out events for the local JID for now
147 157
         if (endpointId !== this.conference.myUserId()) {
158
+
159
+            // Cache the status received received over the data channels, as
160
+            // it will be needed to verify for out of sync when the remote video
161
+            // track is being removed.
162
+            this.rtcConnStatusCache[endpointId] = isActive;
163
+
148 164
             var participant = this.conference.getParticipantById(endpointId);
149 165
             // Delay the 'active' event until the video track gets
150 166
             // the RTC unmuted event
@@ -253,7 +269,64 @@ export default class ParticipantConnectionStatus {
253 269
             remoteTrack.off(
254 270
                 JitsiTrackEvents.TRACK_MUTE_CHANGED,
255 271
                 this._onSignallingMuteChanged);
256
-            this.clearTimeout(remoteTrack.getParticipantId());
272
+
273
+            this.clearTimeout(endpointId);
274
+
275
+            // Only if we're using video muted events - check if the JVB status
276
+            // should be restored from cache.
277
+            if (RTCBrowserType.isVideoMuteOnConnInterruptedSupported())
278
+            {
279
+                this.maybeRestoreCachedStatus(endpointId);
280
+            }
281
+        }
282
+    }
283
+
284
+    /**
285
+     * When RTC video track muted events are taken into account,
286
+     * at the point when the track is being removed we have to update
287
+     * to the current connectivity status according to the JVB. That's
288
+     * because if the current track is muted then the new one which
289
+     * replaces it is always added as unmuted and there may be no
290
+     * 'muted'/'unmuted' event sequence if the connection restores in
291
+     * the meantime.
292
+     *
293
+     * XXX See onEndpointConnStatusChanged method where the update is
294
+     * postponed and which is the cause for this workaround. If we
295
+     * decide to not wait for video unmuted event and accept the JVB
296
+     * status immediately then it's fine to remove the code below.
297
+     */
298
+    maybeRestoreCachedStatus(endpointId) {
299
+        var participant = this.conference.getParticipantById(endpointId);
300
+        if (!participant) {
301
+            // Probably the participant is no longer in the conference
302
+            // (at the time of writing this code, participant is
303
+            // detached from the conference and TRACK_REMOVED events are
304
+            // fired),
305
+            // so we don't care, but let's print the warning for
306
+            // debugging purpose
307
+            logger.warn(
308
+                'maybeRestoreCachedStatus - ' +
309
+                'no participant for endpoint: ' + endpointId);
310
+            return;
311
+        }
312
+
313
+        const isConnectionActive = participant.isConnectionActive();
314
+        const hasAnyVideoRTCMuted = participant.hasAnyVideoTrackWebRTCMuted();
315
+        const isConnActiveByJvb = this.rtcConnStatusCache[endpointId];
316
+
317
+        logger.debug(
318
+            "Remote track removed, is active: " + isConnectionActive
319
+            + " is active(jvb):" + isConnActiveByJvb
320
+            + " video RTC muted:" + hasAnyVideoRTCMuted);
321
+
322
+        if (!isConnectionActive && isConnActiveByJvb && !hasAnyVideoRTCMuted) {
323
+            // FIXME adjust the log level or remove the message completely once
324
+            // the feature gets mature enough.
325
+            logger.info(
326
+                "Remote track removed for disconnected" +
327
+                " participant, when the status according to" +
328
+                " the JVB is connected. Adjusting to the JVB value.");
329
+            this._changeConnectionStatus(endpointId, isConnActiveByJvb);
257 330
         }
258 331
     }
259 332
 

読み込み中…
キャンセル
保存