Procházet zdrojové kódy

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 před 8 roky
rodič
revize
c91362846b
1 změnil soubory, kde provedl 71 přidání a 13 odebrání
  1. 71
    13
      modules/xmpp/JingleSessionPC.js

+ 71
- 13
modules/xmpp/JingleSessionPC.js Zobrazit soubor

@@ -674,8 +674,6 @@ export default class JingleSessionPC extends JingleSession {
674 674
         this.setOfferAnswerCycle(
675 675
             jingleOffer,
676 676
             () => {
677
-                this.state = JingleSessionState.ACTIVE;
678
-
679 677
                 // FIXME we may not care about RESULT packet for session-accept
680 678
                 // then we should either call 'success' here immediately or
681 679
                 // modify sendSessionAccept method to do that
@@ -697,22 +695,49 @@ export default class JingleSessionPC extends JingleSession {
697 695
         if (!this.isInitiator) {
698 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 732
      * Sends 'session-initiate' to the remote peer.
711 733
      * @param {object} sdp the local session description object as defined by
712 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 738
      * @private
714 739
      */
715
-    sendSessionInitiate(sdp) {
740
+    sendSessionInitiate(sdp, success, failure) {
716 741
         logger.log('createdOffer', sdp);
717 742
         const sendJingle = () => {
718 743
             let init = $iq({
@@ -740,12 +765,17 @@ export default class JingleSessionPC extends JingleSession {
740 765
                     logger.error('"session-initiate" error', error);
741 766
                 },
742 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 774
         this.peerconnection.setLocalDescription(
746 775
             sdp, sendJingle,
747 776
             error => {
748 777
                 logger.error('session-init setLocalDescription failed', error);
778
+                failure(error);
749 779
             }
750 780
         );
751 781
     }
@@ -761,7 +791,6 @@ export default class JingleSessionPC extends JingleSession {
761 791
         this.setOfferAnswerCycle(
762 792
             jingleAnswer,
763 793
             () => {
764
-                this.state = JingleSessionState.ACTIVE;
765 794
                 logger.info('setAnswer - succeeded');
766 795
             },
767 796
             error => {
@@ -795,9 +824,27 @@ export default class JingleSessionPC extends JingleSession {
795 824
 
796 825
             const newRemoteSdp
797 826
                 = this._processNewJingleOfferIq(jingleOfferAnswerIq);
827
+            const oldLocalSdp
828
+                = this.peerconnection.localDescription.sdp;
798 829
 
799 830
             this._renegotiate(newRemoteSdp)
800 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 848
                     finishedCallback();
802 849
                 }, error => {
803 850
                     logger.error(
@@ -1310,9 +1357,19 @@ export default class JingleSessionPC extends JingleSession {
1310 1357
      *  rejects with an error {string}
1311 1358
      */
1312 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 1363
         const remoteSdp
1314 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 1373
         const remoteDescription = new RTCSessionDescription({
1317 1374
             type: this.isInitiator ? 'answer' : 'offer',
1318 1375
             sdp: remoteSdp.raw
@@ -1461,7 +1518,8 @@ export default class JingleSessionPC extends JingleSession {
1461 1518
                 this.peerconnection.addTrack(newTrack);
1462 1519
             }
1463 1520
 
1464
-            if ((oldTrack || newTrack) && oldLocalSdp) {
1521
+            if ((oldTrack || newTrack)
1522
+                && this.state === JingleSessionState.ACTIVE) {
1465 1523
                 this._renegotiate()
1466 1524
                     .then(() => {
1467 1525
                         const newLocalSDP

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