Parcourir la source

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 il y a 9 ans
Parent
révision
a5dd7780b1
1 fichiers modifiés avec 74 ajouts et 1 suppressions
  1. 74
    1
      modules/connectivity/ParticipantConnectionStatus.js

+ 74
- 1
modules/connectivity/ParticipantConnectionStatus.js Voir le fichier

40
          * @type {Object.<string, number>}
40
          * @type {Object.<string, number>}
41
          */
41
          */
42
         this.trackTimers = {};
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
          * How long we're going to wait after the RTC video track muted event
51
          * How long we're going to wait after the RTC video track muted event
45
          * for the corresponding signalling mute event, before the connection
52
          * for the corresponding signalling mute event, before the connection
128
         Object.keys(this.trackTimers).forEach(function (participantId) {
135
         Object.keys(this.trackTimers).forEach(function (participantId) {
129
             this.clearTimeout(participantId);
136
             this.clearTimeout(participantId);
130
         }.bind(this));
137
         }.bind(this));
138
+
139
+        // Clear RTC connection status cache
140
+        this.rtcConnStatusCache = {};
131
     }
141
     }
132
 
142
 
133
     /**
143
     /**
145
 
155
 
146
         // Filter out events for the local JID for now
156
         // Filter out events for the local JID for now
147
         if (endpointId !== this.conference.myUserId()) {
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
             var participant = this.conference.getParticipantById(endpointId);
164
             var participant = this.conference.getParticipantById(endpointId);
149
             // Delay the 'active' event until the video track gets
165
             // Delay the 'active' event until the video track gets
150
             // the RTC unmuted event
166
             // the RTC unmuted event
253
             remoteTrack.off(
269
             remoteTrack.off(
254
                 JitsiTrackEvents.TRACK_MUTE_CHANGED,
270
                 JitsiTrackEvents.TRACK_MUTE_CHANGED,
255
                 this._onSignallingMuteChanged);
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
 

Chargement…
Annuler
Enregistrer