Procházet zdrojové kódy

Merge pull request #372 from jitsi/move_jingle_session

Move JingleSessionPC from ChatRoom to JitsiConference
dev1
Paweł Domas před 8 roky
rodič
revize
77ada51d1e

+ 125
- 38
JitsiConference.js Zobrazit soubor

@@ -34,7 +34,7 @@ import ConnectionQuality from "./modules/connectivity/ConnectionQuality";
34 34
  * @constructor
35 35
  */
36 36
 function JitsiConference(options) {
37
-    if(!options.name || options.name.toLowerCase() !== options.name) {
37
+    if (!options.name || options.name.toLowerCase() !== options.name) {
38 38
         var errmsg
39 39
             = "Invalid conference name (no conference name passed or it "
40 40
                 + "contains invalid characters like capital letters)!";
@@ -47,6 +47,11 @@ function JitsiConference(options) {
47 47
     this._init(options);
48 48
     this.componentsVersions = new ComponentsVersions(this);
49 49
     this.participants = {};
50
+    /**
51
+     * Jingle Session instance
52
+     * @type {JingleSessionPC}
53
+     */
54
+    this.jingleSession = null;
50 55
     this.lastDominantSpeaker = null;
51 56
     this.dtmfManager = null;
52 57
     this.somebodySupportsDTMF = false;
@@ -87,12 +92,12 @@ function JitsiConference(options) {
87 92
  * @param connection {JitsiConnection} overrides this.connection
88 93
  */
89 94
 JitsiConference.prototype._init = function (options) {
90
-    if(!options)
95
+    if (!options)
91 96
         options = {};
92 97
 
93 98
     // Override connection and xmpp properties (Usefull if the connection
94 99
     // reloaded)
95
-    if(options.connection) {
100
+    if (options.connection) {
96 101
         this.connection = options.connection;
97 102
         this.xmpp = this.connection.xmpp;
98 103
         // Setup XMPP events only if we have new connection object.
@@ -103,7 +108,7 @@ JitsiConference.prototype._init = function (options) {
103 108
 
104 109
     this.room.updateDeviceAvailability(RTC.getDeviceAvailability());
105 110
 
106
-    if(!this.rtc) {
111
+    if (!this.rtc) {
107 112
         this.rtc = new RTC(this, options);
108 113
         this.eventManager.setupRTCListeners();
109 114
     }
@@ -114,7 +119,7 @@ JitsiConference.prototype._init = function (options) {
114 119
                 options.config.peerDisconnectedThroughRtcTimeout);
115 120
     this.participantConnectionStatus.init();
116 121
 
117
-    if(!this.statistics) {
122
+    if (!this.statistics) {
118 123
         this.statistics = new Statistics(this.xmpp, {
119 124
             callStatsID: this.options.config.callStatsID,
120 125
             callStatsSecret: this.options.config.callStatsSecret,
@@ -144,7 +149,7 @@ JitsiConference.prototype._init = function (options) {
144 149
  * @param password {string} the password
145 150
  */
146 151
 JitsiConference.prototype.join = function (password) {
147
-    if(this.room)
152
+    if (this.room)
148 153
         this.room.join(password);
149 154
 };
150 155
 
@@ -168,7 +173,7 @@ JitsiConference.prototype.leave = function () {
168 173
     this.getLocalTracks().forEach(track => this.onTrackRemoved(track));
169 174
 
170 175
     this.rtc.closeAllDataChannels();
171
-    if(this.statistics)
176
+    if (this.statistics)
172 177
         this.statistics.dispose();
173 178
 
174 179
     // leave the conference
@@ -181,6 +186,11 @@ JitsiConference.prototype.leave = function () {
181 186
             // ChatRoom instance.
182 187
             this.getParticipants().forEach(
183 188
                 participant => this.onMemberLeft(participant.getJid()));
189
+            // Close the JingleSession
190
+            if (this.jingleSession) {
191
+                this.jingleSession.close();
192
+                this.jingleSession = null;
193
+            }
184 194
         });
185 195
     }
186 196
 
@@ -272,7 +282,7 @@ JitsiConference.prototype.getLocalTracks = function (mediaType) {
272 282
  * Note: consider adding eventing functionality by extending an EventEmitter impl, instead of rolling ourselves
273 283
  */
274 284
 JitsiConference.prototype.on = function (eventId, handler) {
275
-    if(this.eventEmitter)
285
+    if (this.eventEmitter)
276 286
         this.eventEmitter.on(eventId, handler);
277 287
 };
278 288
 
@@ -284,7 +294,7 @@ JitsiConference.prototype.on = function (eventId, handler) {
284 294
  * Note: consider adding eventing functionality by extending an EventEmitter impl, instead of rolling ourselves
285 295
  */
286 296
 JitsiConference.prototype.off = function (eventId, handler) {
287
-    if(this.eventEmitter)
297
+    if (this.eventEmitter)
288 298
         this.eventEmitter.removeListener(eventId, handler);
289 299
 };
290 300
 
@@ -299,7 +309,7 @@ JitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;
299 309
  * @param handler {Function} handler for the command
300 310
  */
301 311
  JitsiConference.prototype.addCommandListener = function (command, handler) {
302
-    if(this.room)
312
+    if (this.room)
303 313
         this.room.addPresenceListener(command, handler);
304 314
  };
305 315
 
@@ -308,7 +318,7 @@ JitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;
308 318
   * @param command {String} the name of the command
309 319
   */
310 320
  JitsiConference.prototype.removeCommandListener = function (command) {
311
-    if(this.room)
321
+    if (this.room)
312 322
         this.room.removePresenceListener(command);
313 323
  };
314 324
 
@@ -317,7 +327,7 @@ JitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;
317 327
  * @param message the text message.
318 328
  */
319 329
 JitsiConference.prototype.sendTextMessage = function (message) {
320
-    if(this.room)
330
+    if (this.room)
321 331
         this.room.sendMessage(message);
322 332
 };
323 333
 
@@ -327,7 +337,7 @@ JitsiConference.prototype.sendTextMessage = function (message) {
327 337
  * @param values {Object} with keys and values that will be sent.
328 338
  **/
329 339
 JitsiConference.prototype.sendCommand = function (name, values) {
330
-    if(this.room) {
340
+    if (this.room) {
331 341
         this.room.addToPresence(name, values);
332 342
         this.room.sendPresence();
333 343
     }
@@ -348,7 +358,7 @@ JitsiConference.prototype.sendCommandOnce = function (name, values) {
348 358
  * @param name {String} the name of the command.
349 359
  **/
350 360
 JitsiConference.prototype.removeCommand = function (name) {
351
-    if(this.room)
361
+    if (this.room)
352 362
         this.room.removeFromPresence(name);
353 363
 };
354 364
 
@@ -357,7 +367,7 @@ JitsiConference.prototype.removeCommand = function (name) {
357 367
  * @param name the display name to set
358 368
  */
359 369
 JitsiConference.prototype.setDisplayName = function(name) {
360
-    if(this.room){
370
+    if (this.room){
361 371
         // remove previously set nickname
362 372
         this.room.removeFromPresence("nick");
363 373
 
@@ -381,17 +391,17 @@ JitsiConference.prototype.setSubject = function (subject) {
381 391
  * @return {Transcriber} the transcriber object
382 392
  */
383 393
 JitsiConference.prototype.getTranscriber = function(){
384
-    if(this.transcriber === undefined){
394
+    if (this.transcriber === undefined){
385 395
         this.transcriber = new Transcriber();
386 396
         //add all existing local audio tracks to the transcriber
387 397
         this.rtc.localTracks.forEach(function (localTrack) {
388
-            if(localTrack.isAudioTrack()){
398
+            if (localTrack.isAudioTrack()){
389 399
                 this.transcriber.addTrack(localTrack);
390 400
             }
391 401
         }.bind(this));
392 402
         //and all remote audio tracks
393 403
         this.rtc.remoteTracks.forEach(function (remoteTrack){
394
-            if(remoteTrack.isAudioTrack()){
404
+            if (remoteTrack.isAudioTrack()){
395 405
                 this.transcriber.addTrack(remoteTrack);
396 406
             }
397 407
         }.bind(this));
@@ -476,7 +486,7 @@ JitsiConference.prototype.onTrackRemoved = function (track) {
476 486
 /**
477 487
  * Removes JitsiLocalTrack from the conference and performs
478 488
  * a new offer/answer cycle.
479
- * @param track the JitsiLocalTrack object.
489
+ * @param {JitsiLocalTrack} track
480 490
  * @returns {Promise}
481 491
  */
482 492
 JitsiConference.prototype.removeTrack = function (track) {
@@ -517,7 +527,7 @@ JitsiConference.prototype.replaceTrack = function (oldTrack, newTrack) {
517 527
             newTrack.ssrcHandler);
518 528
     }
519 529
     // Now replace the stream at the lower levels
520
-    return this.room.replaceStream (oldTrack, newTrack)
530
+    return this._doReplaceTrack(oldTrack, newTrack)
521 531
         .then(() => {
522 532
             if (oldTrack) {
523 533
                 this.onTrackRemoved(oldTrack);
@@ -532,6 +542,25 @@ JitsiConference.prototype.replaceTrack = function (oldTrack, newTrack) {
532 542
         });
533 543
 };
534 544
 
545
+/**
546
+ * Replaces the tracks at the lower level by going through the Jingle session
547
+ * and WebRTC peer connection. The method will resolve immediately if there is
548
+ * currently no JingleSession started.
549
+ * @param {JitsiLocalTrack|null} oldTrack the track to be removed during
550
+ * the process or <tt>null</t> if the method should act as "add track"
551
+ * @param {JitsiLocalTrack|null} newTrack the new track to be added or
552
+ * <tt>null</tt> if the method should act as "remove track"
553
+ * @return {Promise}
554
+ * @private
555
+ */
556
+JitsiConference.prototype._doReplaceTrack = function (oldTrack, newTrack) {
557
+    if (this.jingleSession) {
558
+        return this.jingleSession.replaceTrack(oldTrack, newTrack);
559
+    } else {
560
+        return Promise.resolve();
561
+    }
562
+};
563
+
535 564
 /**
536 565
  * Operations related to creating a new track
537 566
  * @param {JitsiLocalTrack} newTrack the new track being created
@@ -590,6 +619,63 @@ JitsiConference.prototype._setupNewTrack = function (newTrack) {
590 619
     this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, newTrack);
591 620
 };
592 621
 
622
+/**
623
+ * Adds loca WebRTC stream to the conference.
624
+ * @param {MediaStream} stream new stream that will be added.
625
+ * @param {function} callback callback executed after successful stream addition.
626
+ * @param {function(error)} errorCallback callback executed if stream addition fail.
627
+ * @param {object} ssrcInfo object with information about the SSRCs associated with the
628
+ * stream.
629
+ * @param {boolean} [dontModifySources] if <tt>true</tt> _modifySources won't be
630
+ * called. The option is used for adding stream, before the Jingle call is
631
+ * started. That is before the 'session-accept' is sent.
632
+ */
633
+JitsiConference.prototype._addLocalStream
634
+    = function (stream, callback, errorCallback, ssrcInfo, dontModifySources) {
635
+    if (this.jingleSession) {
636
+        this.jingleSession.addStream(
637
+            stream, callback, errorCallback, ssrcInfo, dontModifySources);
638
+    } else {
639
+        // We are done immediately
640
+        logger.warn("Add local MediaStream - no JingleSession started yet");
641
+        callback();
642
+    }
643
+};
644
+
645
+/**
646
+ * Remove local WebRTC media stream.
647
+ * @param {MediaStream} stream the stream that will be removed.
648
+ * @param {function} callback callback executed after successful stream removal.
649
+ * @param {function} errorCallback callback executed if stream removal fail.
650
+ * @param {object} ssrcInfo object with information about the SSRCs associated
651
+ * with the stream.
652
+ */
653
+JitsiConference.prototype.removeLocalStream
654
+    = function (stream, callback, errorCallback, ssrcInfo) {
655
+    if (this.jingleSession) {
656
+        this.jingleSession.removeStream(
657
+            stream, callback, errorCallback, ssrcInfo);
658
+    } else {
659
+        // We are done immediately
660
+        logger.warn("Remove local MediaStream - no JingleSession started yet");
661
+        callback();
662
+    }
663
+};
664
+
665
+/**
666
+ * Generate ssrc info object for a stream with the following properties:
667
+ * - ssrcs - Array of the ssrcs associated with the stream.
668
+ * - groups - Array of the groups associated with the stream.
669
+ */
670
+JitsiConference.prototype._generateNewStreamSSRCInfo = function () {
671
+    if (!this.jingleSession) {
672
+        logger.warn("The call haven't been started. " +
673
+            "Cannot generate ssrc info at the moment!");
674
+        return null;
675
+    }
676
+    return this.jingleSession.generateNewStreamSSRCInfo();
677
+};
678
+
593 679
 /**
594 680
  * Get role of the local user.
595 681
  * @returns {string} user role: 'moderator' or 'none'
@@ -825,7 +911,7 @@ JitsiConference.prototype.onTrackAdded = function (track) {
825 911
     // Add track to JitsiParticipant.
826 912
     participant._tracks.push(track);
827 913
 
828
-    if(this.transcriber){
914
+    if (this.transcriber){
829 915
         this.transcriber.addTrack(track);
830 916
     }
831 917
 
@@ -875,7 +961,7 @@ function (jingleSession, jingleOffer, now) {
875 961
     }
876 962
 
877 963
     // Accept incoming call
878
-    this.room.setJingleSession(jingleSession);
964
+    this.jingleSession = jingleSession;
879 965
     this.room.connectionTimes["session.initiate"] = now;
880 966
     // Log "session.restart"
881 967
     if (this.wasStopped) {
@@ -911,7 +997,7 @@ function (jingleSession, jingleOffer, now) {
911 997
          *  problems between sdp-interop and trying to keep the ssrcs
912 998
          *  consistent
913 999
          */
914
-        if(localTrack.isVideoTrack() && localTrack.isMuted() && !RTCBrowserType.isFirefox()) {
1000
+        if (localTrack.isVideoTrack() && localTrack.isMuted() && !RTCBrowserType.isFirefox()) {
915 1001
             /**
916 1002
              * Handles issues when the stream is added before the peerconnection
917 1003
              * is created. The peerconnection is created when second participant
@@ -927,8 +1013,7 @@ function (jingleSession, jingleOffer, now) {
927 1013
              * In order to solve issues like the above one here we have to
928 1014
              * generate the ssrc information for the track .
929 1015
              */
930
-            localTrack._setSSRC(
931
-                this.room.generateNewStreamSSRCInfo());
1016
+            localTrack._setSSRC(this._generateNewStreamSSRCInfo());
932 1017
             ssrcInfo = {
933 1018
                 mtype: localTrack.getType(),
934 1019
                 type: "addMuted",
@@ -937,9 +1022,9 @@ function (jingleSession, jingleOffer, now) {
937 1022
             };
938 1023
         }
939 1024
         try {
940
-            this.room.addStream(
1025
+            this._addLocalStream(
941 1026
                 localTrack.getOriginalStream(), function () {}, function () {},
942
-                ssrcInfo, true);
1027
+                ssrcInfo, true /* don't modify SSRCs */);
943 1028
         } catch(e) {
944 1029
             GlobalOnErrorHandler.callErrorHandler(e);
945 1030
             logger.error(e);
@@ -986,7 +1071,7 @@ JitsiConference.prototype.onCallEnded
986 1071
         this.statistics.stopCallStats();
987 1072
     }
988 1073
     // Current JingleSession is invalid so set it to null on the room
989
-    this.room.setJingleSession(null);
1074
+    this.jingleSession = null;
990 1075
     // Let the RTC service do any cleanups
991 1076
     this.rtc.onCallEnded();
992 1077
     // PeerConnection has been closed which means that SSRCs stored in
@@ -1073,7 +1158,7 @@ JitsiConference.prototype.sendTones = function (tones, duration, pause) {
1073 1158
  * Returns true if recording is supported and false if not.
1074 1159
  */
1075 1160
 JitsiConference.prototype.isRecordingSupported = function () {
1076
-    if(this.room)
1161
+    if (this.room)
1077 1162
         return this.room.isRecordingSupported();
1078 1163
     return false;
1079 1164
 };
@@ -1097,7 +1182,7 @@ JitsiConference.prototype.getRecordingURL = function () {
1097 1182
  * Starts/stops the recording
1098 1183
  */
1099 1184
 JitsiConference.prototype.toggleRecording = function (options) {
1100
-    if(this.room)
1185
+    if (this.room)
1101 1186
         return this.room.toggleRecording(options, function (status, error) {
1102 1187
             this.eventEmitter.emit(
1103 1188
                 JitsiConferenceEvents.RECORDER_STATE_CHANGED, status, error);
@@ -1111,7 +1196,7 @@ JitsiConference.prototype.toggleRecording = function (options) {
1111 1196
  * Returns true if the SIP calls are supported and false otherwise
1112 1197
  */
1113 1198
 JitsiConference.prototype.isSIPCallingSupported = function () {
1114
-    if(this.room)
1199
+    if (this.room)
1115 1200
         return this.room.isSIPCallingSupported();
1116 1201
     return false;
1117 1202
 };
@@ -1121,7 +1206,7 @@ JitsiConference.prototype.isSIPCallingSupported = function () {
1121 1206
  * @param number the number
1122 1207
  */
1123 1208
 JitsiConference.prototype.dial = function (number) {
1124
-    if(this.room)
1209
+    if (this.room)
1125 1210
         return this.room.dial(number);
1126 1211
     return new Promise(function(resolve, reject){
1127 1212
         reject(new Error("The conference is not created yet!"));});
@@ -1131,7 +1216,7 @@ JitsiConference.prototype.dial = function (number) {
1131 1216
  * Hangup an existing call
1132 1217
  */
1133 1218
 JitsiConference.prototype.hangup = function () {
1134
-    if(this.room)
1219
+    if (this.room)
1135 1220
         return this.room.hangup();
1136 1221
     return new Promise(function(resolve, reject){
1137 1222
         reject(new Error("The conference is not created yet!"));});
@@ -1141,7 +1226,7 @@ JitsiConference.prototype.hangup = function () {
1141 1226
  * Returns the phone number for joining the conference.
1142 1227
  */
1143 1228
 JitsiConference.prototype.getPhoneNumber = function () {
1144
-    if(this.room)
1229
+    if (this.room)
1145 1230
         return this.room.getPhoneNumber();
1146 1231
     return null;
1147 1232
 };
@@ -1150,7 +1235,7 @@ JitsiConference.prototype.getPhoneNumber = function () {
1150 1235
  * Returns the pin for joining the conference with phone.
1151 1236
  */
1152 1237
 JitsiConference.prototype.getPhonePin = function () {
1153
-    if(this.room)
1238
+    if (this.room)
1154 1239
         return this.room.getPhonePin();
1155 1240
     return null;
1156 1241
 };
@@ -1160,9 +1245,11 @@ JitsiConference.prototype.getPhonePin = function () {
1160 1245
  * for its session.
1161 1246
  */
1162 1247
 JitsiConference.prototype.getConnectionState = function () {
1163
-    if(this.room)
1164
-        return this.room.getConnectionState();
1165
-    return null;
1248
+    if (this.jingleSession) {
1249
+        return this.jingleSession.getIceConnectionState();
1250
+    } else {
1251
+        return null;
1252
+    }
1166 1253
 };
1167 1254
 
1168 1255
 /**

+ 4
- 4
modules/RTC/JitsiLocalTrack.js Zobrazit soubor

@@ -363,14 +363,14 @@ JitsiLocalTrack.prototype._setMute = function (mute) {
363 363
  * @returns {Promise}
364 364
  */
365 365
 JitsiLocalTrack.prototype._addStreamToConferenceAsUnmute = function () {
366
-    if (!this.conference || !this.conference.room) {
366
+    if (!this.conference) {
367 367
         return Promise.resolve();
368 368
     }
369 369
 
370 370
     var self = this;
371 371
 
372 372
     return new Promise(function(resolve, reject) {
373
-        self.conference.room.addStream(
373
+        self.conference._addLocalStream(
374 374
             self.stream,
375 375
             resolve,
376 376
             (error) => reject(new Error(error)),
@@ -391,12 +391,12 @@ JitsiLocalTrack.prototype._addStreamToConferenceAsUnmute = function () {
391 391
  */
392 392
 JitsiLocalTrack.prototype._removeStreamFromConferenceAsMute =
393 393
 function (successCallback, errorCallback) {
394
-    if (!this.conference || !this.conference.room) {
394
+    if (!this.conference) {
395 395
         successCallback();
396 396
         return;
397 397
     }
398 398
 
399
-    this.conference.room.removeStream(
399
+    this.conference.removeLocalStream(
400 400
         this.stream,
401 401
         successCallback,
402 402
         (error) => errorCallback(new Error(error)),

+ 0
- 92
modules/xmpp/ChatRoom.js Zobrazit soubor

@@ -81,7 +81,6 @@ export default class ChatRoom extends Listenable {
81 81
         this.moderator = new Moderator(this.roomjid, this.xmpp, this.eventEmitter,
82 82
             {connection: this.xmpp.options, conference: this.options});
83 83
         this.initPresenceMap();
84
-        this.session = null;
85 84
         this.lastPresences = {};
86 85
         this.phoneNumber = null;
87 86
         this.phonePin = null;
@@ -705,78 +704,6 @@ export default class ChatRoom extends Listenable {
705 704
         return null;
706 705
     }
707 706
 
708
-    setJingleSession (session){
709
-        this.session = session;
710
-    }
711
-
712
-    /**
713
-     * Replaces oldStream with newStream and performs a single offer/answer
714
-     *  cycle after both operations are done.  Either oldStream or newStream
715
-     *  can be null; replacing a valid 'oldStream' with a null 'newStream'
716
-     *  effectively just removes 'oldStream'
717
-     * @param oldStream the current stream in use to be replaced
718
-     * @param newStream the new stream to use
719
-     * @returns {Promise}
720
-     */
721
-    replaceStream (oldStream, newStream) {
722
-        if (this.session) {
723
-            return this.session.replaceStream(oldStream, newStream);
724
-        }
725
-        return Promise.resolve();
726
-    }
727
-
728
-    /**
729
-     * Remove stream.
730
-     * @param stream stream that will be removed.
731
-     * @param callback callback executed after successful stream removal.
732
-     * @param errorCallback callback executed if stream removal fail.
733
-     * @param ssrcInfo object with information about the SSRCs associated with the
734
-     * stream.
735
-     */
736
-    removeStream (stream, callback, errorCallback, ssrcInfo) {
737
-        if(!this.session) {
738
-            callback();
739
-            return;
740
-        }
741
-        this.session.removeStream(stream, callback, errorCallback, ssrcInfo);
742
-    }
743
-
744
-    /**
745
-     * Adds stream.
746
-     * @param stream new stream that will be added.
747
-     * @param callback callback executed after successful stream addition.
748
-     * @param errorCallback callback executed if stream addition fail.
749
-     * @param ssrcInfo object with information about the SSRCs associated with the
750
-     * stream.
751
-     * @param dontModifySources {boolean} if true _modifySources won't be called.
752
-     * Used for streams added before the call start.
753
-     */
754
-    addStream (stream, callback, errorCallback, ssrcInfo, dontModifySources) {
755
-        if(this.session) {
756
-            // FIXME: will block switchInProgress on true value in case of exception
757
-            this.session.addStream(stream, callback, errorCallback, ssrcInfo,
758
-                dontModifySources);
759
-        } else {
760
-            // We are done immediately
761
-            logger.warn("No conference handler or conference not started yet");
762
-            callback();
763
-        }
764
-    }
765
-
766
-    /**
767
-     * Generate ssrc info object for a stream with the following properties:
768
-     * - ssrcs - Array of the ssrcs associated with the stream.
769
-     * - groups - Array of the groups associated with the stream.
770
-     */
771
-    generateNewStreamSSRCInfo () {
772
-        if(!this.session) {
773
-            logger.warn("The call haven't been started. " +
774
-                "Cannot generate ssrc info at the moment!");
775
-            return null;
776
-        }
777
-        return this.session.generateNewStreamSSRCInfo();
778
-    }
779
-
780 707
     setVideoMute (mute, callback) {
781 708
         this.sendVideoInfoPresence(mute);
782 709
         if(callback)
@@ -926,15 +853,6 @@ export default class ChatRoom extends Listenable {
926 853
         return this.phonePin;
927 854
     }
928 855
 
929
-    /**
930
-     * Returns the connection state for the current session.
931
-     */
932
-    getConnectionState () {
933
-        if(!this.session)
934
-            return null;
935
-        return this.session.getIceConnectionState();
936
-    }
937
-
938 856
     /**
939 857
      * Mutes remote participant.
940 858
      * @param jid of the participant
@@ -982,7 +900,6 @@ export default class ChatRoom extends Listenable {
982 900
      * rejected.
983 901
      */
984 902
     leave () {
985
-        this._dispose();
986 903
         return new Promise((resolve, reject) => {
987 904
             let timeout = setTimeout(() => onMucLeft(true), 5000);
988 905
             let eventEmitter = this.eventEmitter;
@@ -1001,13 +918,4 @@ export default class ChatRoom extends Listenable {
1001 918
             this.doLeave();
1002 919
         });
1003 920
     }
1004
-
1005
-    /**
1006
-     * Disposes the conference, closes the jingle session.
1007
-     */
1008
-    _dispose () {
1009
-        if (this.session) {
1010
-            this.session.close();
1011
-        }
1012
-    }
1013 921
 }

+ 1
- 11
modules/xmpp/JingleSession.js Zobrazit soubor

@@ -9,7 +9,7 @@ const logger = getLogger(__filename);
9 9
 import * as JingleSessionState from "./JingleSessionState";
10 10
 
11 11
 function JingleSession(me, sid, peerjid, connection,
12
-                       media_constraints, ice_config, service, eventEmitter) {
12
+                       media_constraints, ice_config) {
13 13
     /**
14 14
      * Our JID.
15 15
      */
@@ -30,16 +30,6 @@ function JingleSession(me, sid, peerjid, connection,
30 30
      */
31 31
     this.connection = connection;
32 32
 
33
-    /**
34
-     * The XMPP service.
35
-     */
36
-    this.service = service;
37
-
38
-    /**
39
-     * The event emitter.
40
-     */
41
-    this.eventEmitter = eventEmitter;
42
-
43 33
     /**
44 34
      * Whether to use dripping or not. Dripping is sending trickle candidates
45 35
      * not one-by-one.

+ 49
- 19
modules/xmpp/JingleSessionPC.js Zobrazit soubor

@@ -23,11 +23,30 @@ import * as JingleSessionState from "./JingleSessionState";
23 23
  */
24 24
 var IQ_TIMEOUT = 10000;
25 25
 
26
-// Jingle stuff
26
+/**
27
+ * Creates new <tt>JingleSessionPC</tt>
28
+ * @param {string} me our JID
29
+ * @param {string} sid the Jingle Session ID - random string which
30
+ * identifies the session
31
+ * @param {string} peerjid remote peer JID
32
+ * @param {Strophe.Connection} connection Strophe XMPP connection instance
33
+ * used to send packets.
34
+ * @param media_constraints the media constraints object passed to
35
+ * createOffer/Answer, as defined by the WebRTC standard
36
+ * @param ice_config the ICE servers config object as defined by the WebRTC
37
+ * standard.
38
+ * @param {object} options a set of config options
39
+ * @param {boolean} options.webrtcIceUdpDisable <tt>true</tt> to block UDP
40
+ * candidates.
41
+ * @param {boolean} options.webrtcIceTcpDisable <tt>true</tt> to block TCP
42
+ * candidates.
43
+ * @param {boolean} options.failICE it's an option used in the tests. Set to
44
+ * <tt>true</tt> to block any real candidates and make the ICE fail.
45
+ */
27 46
 function JingleSessionPC(me, sid, peerjid, connection,
28
-                         media_constraints, ice_config, service, eventEmitter) {
47
+                         media_constraints, ice_config, options) {
29 48
     JingleSession.call(this, me, sid, peerjid, connection,
30
-                       media_constraints, ice_config, service, eventEmitter);
49
+                       media_constraints, ice_config);
31 50
 
32 51
     this.lasticecandidate = false;
33 52
     this.closed = false;
@@ -60,14 +79,14 @@ function JingleSessionPC(me, sid, peerjid, connection,
60 79
      */
61 80
     this.ssrcOwners = {};
62 81
 
63
-    this.webrtcIceUdpDisable = !!this.service.options.webrtcIceUdpDisable;
64
-    this.webrtcIceTcpDisable = !!this.service.options.webrtcIceTcpDisable;
82
+    this.webrtcIceUdpDisable = !!options.webrtcIceUdpDisable;
83
+    this.webrtcIceTcpDisable = !!options.webrtcIceTcpDisable;
65 84
     /**
66 85
      * Flag used to enforce ICE failure through the URL parameter for
67 86
      * the automatic testing purpose.
68 87
      * @type {boolean}
69 88
      */
70
-    this.failICE = !!this.service.options.failICE;
89
+    this.failICE = !!options.failICE;
71 90
 
72 91
     this.modificationQueue = async.queue(this._processQueueTasks.bind(this), 1);
73 92
 }
@@ -85,9 +104,19 @@ JingleSessionPC.prototype.doInitialize = function () {
85 104
     this.wasstable = false;
86 105
 
87 106
     this.peerconnection = new TraceablePeerConnection(
88
-            this.connection.jingle.ice_config,
89
-            RTC.getPCConstraints(),
90
-            this);
107
+        this.connection.jingle.ice_config,
108
+        RTC.getPCConstraints(),
109
+        /* Options */
110
+        {
111
+            disableSimulcast: this.room.options.disableSimulcast,
112
+            disableRtx: this.room.options.disableRtx,
113
+            preferH264: this.room.options.preferH264
114
+        },
115
+        // TPC is using room's eventEmitter, so that all XMPPEvents can be
116
+        // captured from ChatRoom. But at the same time it makes hard
117
+        // or impossible to deal with more than one TPC instance without
118
+        // further refactoring.
119
+        this.room.eventEmitter);
91 120
 
92 121
     this.peerconnection.onicecandidate = function (ev) {
93 122
         if (!ev) {
@@ -240,7 +269,7 @@ JingleSessionPC.prototype.sendIceCandidates = function (candidates) {
240 269
             for (var i = 0; i < cands.length; i++) {
241 270
                 var candidate = SDPUtil.candidateToJingle(cands[i].candidate);
242 271
                 // Mangle ICE candidate if 'failICE' test option is enabled
243
-                if (this.service.options.failICE) {
272
+                if (this.failICE) {
244 273
                     candidate.ip = "1.1.1.1";
245 274
                 }
246 275
                 cand.c('candidate', candidate).up();
@@ -846,24 +875,25 @@ JingleSessionPC.prototype._renegotiate = function(optionalRemoteSdp) {
846 875
  *  cycle after both operations are done.  Either oldStream or newStream
847 876
  *  can be null; replacing a valid 'oldStream' with a null 'newStream'
848 877
  *  effectively just removes 'oldStream'
849
- * @param oldStream the current stream in use to be replaced
850
- * @param newStream the new stream to use
878
+ * @param {JitsiLocalTrack|null} oldTrack the current track in use to be
879
+ * replaced
880
+ * @param {JitsiLocalTrack|null} newTrack the new track to use
851 881
  * @returns {Promise} which resolves once the replacement is complete
852 882
  *  with no arguments or rejects with an error {string}
853 883
  */
854
-JingleSessionPC.prototype.replaceStream = function (oldStream, newStream) {
884
+JingleSessionPC.prototype.replaceTrack = function (oldTrack, newTrack) {
855 885
     return new Promise((resolve, reject) => {
856 886
         let workFunction = (finishedCallback) => {
857 887
             let oldSdp = new SDP(this.peerconnection.localDescription.sdp);
858
-            this.removeStreamFromPeerConnection(oldStream);
859
-            this.addStreamToPeerConnection(newStream);
888
+            this.removeStreamFromPeerConnection(oldTrack);
889
+            this.addStreamToPeerConnection(newTrack);
860 890
             this._renegotiate()
861 891
                 .then(() => {
862 892
                     var newSdp = new SDP(this.peerconnection.localDescription.sdp);
863 893
                     this.notifyMySSRCUpdate(oldSdp, newSdp);
864 894
                     finishedCallback();
865 895
                 }, (error) => {
866
-                    logger.error("replaceStream renegotiation failed: " + error);
896
+                    logger.error("replaceTrack renegotiation failed: " + error);
867 897
                     finishedCallback(error);
868 898
                 });
869 899
         };
@@ -952,11 +982,11 @@ JingleSessionPC.prototype._parseSsrcInfoFromSourceRemove = function (sourceRemov
952 982
  * stream.
953 983
  * @param dontModifySources {boolean} if true _modifySources won't be called.
954 984
  * Used for streams added before the call start.
955
- * NOTE(brian): there is a decent amount of overlap here with replaceStream that
985
+ * NOTE(brian): there is a decent amount of overlap here with replaceTrack that
956 986
  *  could be re-used...however we can't leverage that currently because the
957 987
  *  extra work we do here must be in the work function context and if we
958
- *  then called replaceStream we'd be adding another task on the queue
959
- *  from within a task which would then deadlock.  The 'replaceStream' core
988
+ *  then called replaceTrack we'd be adding another task on the queue
989
+ *  from within a task which would then deadlock.  The 'replaceTrack' core
960 990
  *  logic should be moved into a helper function that could be called within
961 991
  *  the 'doReplaceStream' task or the 'doAddStream' task (for example)
962 992
  */

+ 28
- 11
modules/xmpp/TraceablePeerConnection.js Zobrazit soubor

@@ -12,9 +12,26 @@ var SDPUtil = require("./SDPUtil");
12 12
 
13 13
 var SIMULCAST_LAYERS = 3;
14 14
 
15
-function TraceablePeerConnection(ice_config, constraints, session) {
15
+/**
16
+ * Creates new instance of 'TraceablePeerConnection'.
17
+ *
18
+ * @param {object} ice_config WebRTC 'PeerConnection' ICE config
19
+ * @param {object} constraints WebRTC 'PeerConnection' constraints
20
+ * @param {object} options <tt>TracablePeerConnection</tt> config options.
21
+ * @param {boolean} options.disableSimulcast if set to 'true' will disable
22
+ * the simulcast
23
+ * @param {boolean} options.disableRtx if set to 'true' will disable the RTX
24
+ * @param {boolean} options.preferH264 if set to 'true' H264 will be preferred
25
+ * over other video codecs.
26
+ * @param {EventEmitter} eventEmitter the emitter which wil be used by the new
27
+ * instance to emit events.
28
+ *
29
+ * @constructor
30
+ */
31
+function TraceablePeerConnection(ice_config,
32
+                                 constraints, options, eventEmitter) {
16 33
     var self = this;
17
-    this.session = session;
34
+    this.options = options;
18 35
     var RTCPeerConnectionType = null;
19 36
     if (RTCBrowserType.isFirefox()) {
20 37
         RTCPeerConnectionType = mozRTCPeerConnection;
@@ -35,7 +52,7 @@ function TraceablePeerConnection(ice_config, constraints, session) {
35 52
         explodeRemoteSimulcast: false});
36 53
     this.sdpConsistency = new SdpConsistency();
37 54
     this.rtxModifier = new RtxModifier();
38
-    this.eventEmitter = this.session.room.eventEmitter;
55
+    this.eventEmitter = eventEmitter;
39 56
 
40 57
     // override as desired
41 58
     this.trace = function (what, info) {
@@ -318,7 +335,7 @@ TraceablePeerConnection.prototype.addStream = function (stream, ssrcInfo) {
318 335
         this.peerconnection.addStream(stream);
319 336
     if (ssrcInfo && ssrcInfo.type === "addMuted") {
320 337
         this.sdpConsistency.setPrimarySsrc(ssrcInfo.ssrc.ssrcs[0]);
321
-        const simGroup = 
338
+        const simGroup =
322 339
             ssrcInfo.ssrc.groups.find(groupInfo => {
323 340
                 return groupInfo.group.semantics === "SIM";
324 341
             });
@@ -333,7 +350,7 @@ TraceablePeerConnection.prototype.addStream = function (stream, ssrcInfo) {
333 350
         if (fidGroups) {
334 351
             const rtxSsrcMapping = new Map();
335 352
             fidGroups.forEach(fidGroup => {
336
-                const fidGroupSsrcs = 
353
+                const fidGroupSsrcs =
337 354
                     SDPUtil.parseGroupSsrcs(fidGroup.group);
338 355
                 const primarySsrc = fidGroupSsrcs[0];
339 356
                 const rtxSsrc = fidGroupSsrcs[1];
@@ -389,7 +406,7 @@ TraceablePeerConnection.prototype.setRemoteDescription
389 406
     description = this.simulcast.mungeRemoteDescription(description);
390 407
     this.trace('setRemoteDescription::postTransform (simulcast)', dumpSDP(description));
391 408
 
392
-    if (this.session.room.options.preferH264) {
409
+    if (this.options.preferH264) {
393 410
         const parsedSdp = transform.parse(description.sdp);
394 411
         const videoMLine = parsedSdp.media.find(m => m.type === "video");
395 412
         SDPUtil.preferVideoCodec(videoMLine, "h264");
@@ -539,7 +556,7 @@ TraceablePeerConnection.prototype.createAnswer
539 556
                 }
540 557
 
541 558
                 // Add simulcast streams if simulcast is enabled
542
-                if (!this.session.room.options.disableSimulcast
559
+                if (!this.options.disableSimulcast
543 560
                     && this.simulcast.isSupported()) {
544 561
                     answer = this.simulcast.mungeLocalDescription(answer);
545 562
                     this.trace(
@@ -547,7 +564,7 @@ TraceablePeerConnection.prototype.createAnswer
547 564
                         dumpSDP(answer));
548 565
                 }
549 566
 
550
-                if (!this.session.room.options.disableRtx && !RTCBrowserType.isFirefox()) {
567
+                if (!this.options.disableRtx && !RTCBrowserType.isFirefox()) {
551 568
                     answer.sdp = this.rtxModifier.modifyRtxSsrcs(answer.sdp);
552 569
                     this.trace(
553 570
                         'createAnswerOnSuccess::postTransform (rtx modifier)',
@@ -623,7 +640,7 @@ TraceablePeerConnection.prototype.getStats = function(callback, errback) {
623 640
  */
624 641
 TraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function () {
625 642
     let ssrcInfo = {ssrcs: [], groups: []};
626
-    if (!this.session.room.options.disableSimulcast
643
+    if (!this.options.disableSimulcast
627 644
         && this.simulcast.isSupported()) {
628 645
         for (let i = 0; i < SIMULCAST_LAYERS; i++) {
629 646
             ssrcInfo.ssrcs.push(SDPUtil.generateSsrc());
@@ -635,7 +652,7 @@ TraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function () {
635 652
     } else {
636 653
         ssrcInfo = {ssrcs: [SDPUtil.generateSsrc()], groups: []};
637 654
     }
638
-    if (!this.session.room.options.disableRtx) {
655
+    if (!this.options.disableRtx) {
639 656
         // Specifically use a for loop here because we'll
640 657
         //  be adding to the list we're iterating over, so we
641 658
         //  only want to iterate through the items originally
@@ -647,7 +664,7 @@ TraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function () {
647 664
             ssrcInfo.ssrcs.push(rtxSsrc);
648 665
             ssrcInfo.groups.push({
649 666
                 primarySSRC: primarySsrc,
650
-                group: { 
667
+                group: {
651 668
                     ssrcs: primarySsrc + " " + rtxSsrc,
652 669
                     semantics: "FID"
653 670
                 }

+ 0
- 8
modules/xmpp/strophe.emuc.js Zobrazit soubor

@@ -106,14 +106,6 @@ class MucConnectionPlugin extends ConnectionPluginListenable {
106 106
         return true;
107 107
     }
108 108
 
109
-    setJingleSession (from, session) {
110
-        const room = this.rooms[Strophe.getBareJidFromJid(from)];
111
-        if(!room)
112
-            return;
113
-
114
-        room.setJingleSession(session);
115
-    }
116
-
117 109
     onMute(iq) {
118 110
         const from = iq.getAttribute('from');
119 111
         const room = this.rooms[Strophe.getBareJidFromJid(from)];

+ 1
- 1
modules/xmpp/strophe.jingle.js Zobrazit soubor

@@ -90,7 +90,7 @@ class JingleConnectionPlugin extends ConnectionPlugin {
90 90
                         fromJid,
91 91
                         this.connection,
92 92
                         this.media_constraints,
93
-                        this.ice_config, this.xmpp);
93
+                        this.ice_config, this.xmpp.options);
94 94
 
95 95
                 this.sessions[sess.sid] = sess;
96 96
 

Načítá se…
Zrušit
Uložit