瀏覽代碼

fix(JingleSessionPC): execute 'invite' on the queue

Invite must be executed on the queue to avoid strange things happening
on the beginning of the call. For example when the local tracks are
added just after the invite was called.

Move the JingleSessionPC to ACTIVE state, as soon as the first
_renegotiate is executed in PENDING state.
master
paweldomas 8 年之前
父節點
當前提交
c91362846b
共有 1 個檔案被更改,包括 71 行新增13 行删除
  1. 71
    13
      modules/xmpp/JingleSessionPC.js

+ 71
- 13
modules/xmpp/JingleSessionPC.js 查看文件

674
         this.setOfferAnswerCycle(
674
         this.setOfferAnswerCycle(
675
             jingleOffer,
675
             jingleOffer,
676
             () => {
676
             () => {
677
-                this.state = JingleSessionState.ACTIVE;
678
-
679
                 // FIXME we may not care about RESULT packet for session-accept
677
                 // FIXME we may not care about RESULT packet for session-accept
680
                 // then we should either call 'success' here immediately or
678
                 // then we should either call 'success' here immediately or
681
                 // modify sendSessionAccept method to do that
679
                 // modify sendSessionAccept method to do that
697
         if (!this.isInitiator) {
695
         if (!this.isInitiator) {
698
             throw new Error('Trying to invite from the responder session');
696
             throw new Error('Trying to invite from the responder session');
699
         }
697
         }
700
-        for (const localTrack of localTracks) {
701
-            this.peerconnection.addTrack(localTrack);
702
-        }
703
-        this.peerconnection.createOffer(
704
-            this.sendSessionInitiate.bind(this),
705
-            error => logger.error('Failed to create offer', error),
706
-            this.mediaConstraints);
698
+        const workFunction = finishedCallback => {
699
+            for (const localTrack of localTracks) {
700
+                this.peerconnection.addTrack(localTrack);
701
+            }
702
+            this.peerconnection.createOffer(
703
+                sdp => {
704
+                    this.sendSessionInitiate(
705
+                        sdp,
706
+                        finishedCallback,
707
+                        finishedCallback
708
+                    );
709
+                },
710
+                error => {
711
+                    logger.error(
712
+                        'Failed to create an offer',
713
+                        error,
714
+                        this.mediaConstraints);
715
+                    finishedCallback(error);
716
+                },
717
+                this.mediaConstraints);
718
+        };
719
+
720
+        this.modificationQueue.push(
721
+            workFunction,
722
+            error => {
723
+                if (error) {
724
+                    logger.error('invite error', error);
725
+                } else {
726
+                    logger.debug('invite executed - OK');
727
+                }
728
+            });
707
     }
729
     }
708
 
730
 
709
     /**
731
     /**
710
      * Sends 'session-initiate' to the remote peer.
732
      * Sends 'session-initiate' to the remote peer.
711
      * @param {object} sdp the local session description object as defined by
733
      * @param {object} sdp the local session description object as defined by
712
      * the WebRTC standard.
734
      * the WebRTC standard.
735
+     * @param {function} success executed when the operation succeeds.
736
+     * @param {function(error)} failure executed when the operation fails with
737
+     * an error passed as an argument.
713
      * @private
738
      * @private
714
      */
739
      */
715
-    sendSessionInitiate(sdp) {
740
+    sendSessionInitiate(sdp, success, failure) {
716
         logger.log('createdOffer', sdp);
741
         logger.log('createdOffer', sdp);
717
         const sendJingle = () => {
742
         const sendJingle = () => {
718
             let init = $iq({
743
             let init = $iq({
740
                     logger.error('"session-initiate" error', error);
765
                     logger.error('"session-initiate" error', error);
741
                 },
766
                 },
742
                 IQ_TIMEOUT);
767
                 IQ_TIMEOUT);
768
+
769
+            // NOTE the callback is executed immediately as we don't want to
770
+            // wait for the XMPP response which would delay the startup process.
771
+            success();
743
         };
772
         };
744
 
773
 
745
         this.peerconnection.setLocalDescription(
774
         this.peerconnection.setLocalDescription(
746
             sdp, sendJingle,
775
             sdp, sendJingle,
747
             error => {
776
             error => {
748
                 logger.error('session-init setLocalDescription failed', error);
777
                 logger.error('session-init setLocalDescription failed', error);
778
+                failure(error);
749
             }
779
             }
750
         );
780
         );
751
     }
781
     }
761
         this.setOfferAnswerCycle(
791
         this.setOfferAnswerCycle(
762
             jingleAnswer,
792
             jingleAnswer,
763
             () => {
793
             () => {
764
-                this.state = JingleSessionState.ACTIVE;
765
                 logger.info('setAnswer - succeeded');
794
                 logger.info('setAnswer - succeeded');
766
             },
795
             },
767
             error => {
796
             error => {
795
 
824
 
796
             const newRemoteSdp
825
             const newRemoteSdp
797
                 = this._processNewJingleOfferIq(jingleOfferAnswerIq);
826
                 = this._processNewJingleOfferIq(jingleOfferAnswerIq);
827
+            const oldLocalSdp
828
+                = this.peerconnection.localDescription.sdp;
798
 
829
 
799
             this._renegotiate(newRemoteSdp)
830
             this._renegotiate(newRemoteSdp)
800
                 .then(() => {
831
                 .then(() => {
832
+                    if (this.state === JingleSessionState.PENDING) {
833
+                        this.state = JingleSessionState.ACTIVE;
834
+                    }
835
+
836
+                    // Old local SDP will be available when we're setting answer
837
+                    // for the first time, but not when offer and it's fine
838
+                    // since we're generating an answer now it will contain all
839
+                    // our SSRCs
840
+                    if (oldLocalSdp) {
841
+                        const newLocalSdp
842
+                            = new SDP(this.peerconnection.localDescription.sdp);
843
+
844
+                        this.notifyMySSRCUpdate(
845
+                            new SDP(oldLocalSdp), newLocalSdp);
846
+                    }
847
+
801
                     finishedCallback();
848
                     finishedCallback();
802
                 }, error => {
849
                 }, error => {
803
                     logger.error(
850
                     logger.error(
1310
      *  rejects with an error {string}
1357
      *  rejects with an error {string}
1311
      */
1358
      */
1312
     _renegotiate(optionalRemoteSdp) {
1359
     _renegotiate(optionalRemoteSdp) {
1360
+        const currentRemoteSdp = this.peerconnection.remoteDescription.sdp;
1361
+
1362
+        // FIXME new SDP() may not be necessary - raw SDP is needed anyway
1313
         const remoteSdp
1363
         const remoteSdp
1314
             = optionalRemoteSdp
1364
             = optionalRemoteSdp
1315
-                || new SDP(this.peerconnection.remoteDescription.sdp);
1365
+                || (currentRemoteSdp && new SDP(currentRemoteSdp));
1366
+
1367
+        if (!remoteSdp) {
1368
+            return Promise.reject(
1369
+                'Can not renegotiate without remote description,'
1370
+                    + `- current state: ${this.state}`);
1371
+        }
1372
+
1316
         const remoteDescription = new RTCSessionDescription({
1373
         const remoteDescription = new RTCSessionDescription({
1317
             type: this.isInitiator ? 'answer' : 'offer',
1374
             type: this.isInitiator ? 'answer' : 'offer',
1318
             sdp: remoteSdp.raw
1375
             sdp: remoteSdp.raw
1461
                 this.peerconnection.addTrack(newTrack);
1518
                 this.peerconnection.addTrack(newTrack);
1462
             }
1519
             }
1463
 
1520
 
1464
-            if ((oldTrack || newTrack) && oldLocalSdp) {
1521
+            if ((oldTrack || newTrack)
1522
+                && this.state === JingleSessionState.ACTIVE) {
1465
                 this._renegotiate()
1523
                 this._renegotiate()
1466
                     .then(() => {
1524
                     .then(() => {
1467
                         const newLocalSDP
1525
                         const newLocalSDP

Loading…
取消
儲存