Преглед изворни кода

Merge pull request #233 from jitsi/session-terminate

Handle session-terminate
master
hristoterezov пре 9 година
родитељ
комит
c830d0e81c

+ 51
- 1
JitsiConference.js Прегледај датотеку

57
     };
57
     };
58
     this.isMutedByFocus = false;
58
     this.isMutedByFocus = false;
59
     this.reportedAudioSSRCs = {};
59
     this.reportedAudioSSRCs = {};
60
+    // Flag indicates if the 'onCallEnded' method was ever called on this
61
+    // instance. Used to log extra analytics event for debugging purpose.
62
+    // We need to know if the potential issue happened before or after
63
+    // the restart.
64
+    this.wasStopped = false;
60
 }
65
 }
61
 
66
 
62
 /**
67
 /**
786
     // Accept incoming call
791
     // Accept incoming call
787
     this.room.setJingleSession(jingleSession);
792
     this.room.setJingleSession(jingleSession);
788
     this.room.connectionTimes["session.initiate"] = now;
793
     this.room.connectionTimes["session.initiate"] = now;
794
+    // Log "session.restart"
795
+    if (this.wasStopped) {
796
+        Statistics.sendEventToAll("session.restart");
797
+    }
789
     // add info whether call is cross-region
798
     // add info whether call is cross-region
790
     var crossRegion = null;
799
     var crossRegion = null;
791
     if (window.jitsiRegionInfo)
800
     if (window.jitsiRegionInfo)
852
     // both camera and microphone.
861
     // both camera and microphone.
853
     this.statistics.startCallStats(jingleSession, this.settings);
862
     this.statistics.startCallStats(jingleSession, this.settings);
854
     this.statistics.startRemoteStats(jingleSession.peerconnection);
863
     this.statistics.startRemoteStats(jingleSession.peerconnection);
855
-}
864
+};
865
+
866
+/**
867
+ * Handles the call ended event.
868
+ * @param {JingleSessionPC} JingleSession the jingle session which has been
869
+ * terminated.
870
+ * @param {String} reasonCondition the Jingle reason condition.
871
+ * @param {String|null} reasonText human readable reason text which may provide
872
+ * more details about why the call has been terminated.
873
+ */
874
+JitsiConference.prototype.onCallEnded
875
+= function (JingleSession, reasonCondition, reasonText) {
876
+    logger.info("Call ended: " + reasonCondition + " - " + reasonText);
877
+    this.wasStopped = true;
878
+    // Send session.terminate event
879
+    Statistics.sendEventToAll("session.terminate");
880
+    // Stop the stats
881
+    if (this.statistics) {
882
+        this.statistics.stopRemoteStats();
883
+        this.statistics.stopCallStats();
884
+    }
885
+    // Current JingleSession is invalid so set it to null on the room
886
+    this.room.setJingleSession(null);
887
+    // Let the RTC service do any cleanups
888
+    this.rtc.onCallEnded();
889
+    // PeerConnection has been closed which means that SSRCs stored in
890
+    // JitsiLocalTrack will not match those assigned by the old PeerConnection
891
+    // and SSRC replacement logic will not work as expected.
892
+    // We want to re-register 'ssrcHandler' of our local tracks, so that they
893
+    // will learn what their SSRC from the new PeerConnection which will be
894
+    // created on incoming call event.
895
+    var self = this;
896
+    this.rtc.localTracks.forEach(function(localTrack) {
897
+        // Reset SSRC as it will no longer be valid
898
+        localTrack._setSSRC(null);
899
+        // Bind the handler to fetch new SSRC, it will un register itself once
900
+        // it reads the values
901
+        self.room.addListener(
902
+            XMPPEvents.SENDRECV_STREAMS_CHANGED, localTrack.ssrcHandler);
903
+    });
904
+};
905
+
856
 
906
 
857
 JitsiConference.prototype.updateDTMFSupport = function () {
907
 JitsiConference.prototype.updateDTMFSupport = function () {
858
     var somebodySupportsDTMF = false;
908
     var somebodySupportsDTMF = false;

+ 2
- 0
JitsiConferenceEventManager.js Прегледај датотеку

487
     var conference = this.conference;
487
     var conference = this.conference;
488
     conference.xmpp.addListener(
488
     conference.xmpp.addListener(
489
         XMPPEvents.CALL_INCOMING, conference.onIncomingCall.bind(conference));
489
         XMPPEvents.CALL_INCOMING, conference.onIncomingCall.bind(conference));
490
+    conference.xmpp.addListener(
491
+        XMPPEvents.CALL_ENDED, conference.onCallEnded.bind(conference));
490
 
492
 
491
     conference.xmpp.addListener(XMPPEvents.START_MUTED_FROM_FOCUS,
493
     conference.xmpp.addListener(XMPPEvents.START_MUTED_FROM_FOCUS,
492
         function (audioMuted, videoMuted) {
494
         function (audioMuted, videoMuted) {

+ 14
- 0
modules/RTC/RTC.js Прегледај датотеку

89
             this.eventEmitter);
89
             this.eventEmitter);
90
 };
90
 };
91
 
91
 
92
+/**
93
+ * Should be called when current media session ends and after the PeerConnection
94
+ * has been closed using PeerConnection.close() method.
95
+ */
96
+RTC.prototype.onCallEnded = function() {
97
+    if (this.dataChannels) {
98
+        // DataChannels are not explicitly closed as the PeerConnection
99
+        // is closed on call ended which triggers data channel onclose events.
100
+        // The reference is cleared to disable any logic related to the data
101
+        // channels.
102
+        this.dataChannels = null;
103
+    }
104
+};
105
+
92
 /**
106
 /**
93
  * Elects the participant with the given id to be the pinned participant in
107
  * Elects the participant with the given id to be the pinned participant in
94
  * order to always receive video for this participant (even when last n is
108
  * order to always receive video for this participant (even when last n is

+ 14
- 2
modules/statistics/statistics.js Прегледај датотеку

124
     if(this.callStatsIntegrationEnabled)
124
     if(this.callStatsIntegrationEnabled)
125
         loadCallStatsAPI();
125
         loadCallStatsAPI();
126
     this.callStats = null;
126
     this.callStats = null;
127
+    // Flag indicates whether or not the CallStats have been started for this
128
+    // Statistics instance
129
+    this.callStatsStarted = false;
127
 
130
 
128
     /**
131
     /**
129
      * Send the stats already saved in rtpStats to be logged via the focus.
132
      * Send the stats already saved in rtpStats to be logged via the focus.
252
  * /modules/settings/Settings.js
255
  * /modules/settings/Settings.js
253
  */
256
  */
254
 Statistics.prototype.startCallStats = function (session, settings) {
257
 Statistics.prototype.startCallStats = function (session, settings) {
255
-    if(this.callStatsIntegrationEnabled && !this.callstats) {
258
+    if(this.callStatsIntegrationEnabled && !this.callStatsStarted) {
259
+        // Here we overwrite the previous instance, but it must be bound to
260
+        // the new PeerConnection
261
+        // FIXME CallStats does not show the participant after
262
+        // stopCallStats/startCallStats, the issue is being investigated on both
263
+        // our and CallStats side, but given how rare this situation should
264
+        // be, we need to have this change merged. Without it "invalid pcHash"
265
+        // error is reported(lib calls are made for the old PeerConnection).
256
         this.callstats = new CallStats(session, settings, this.options);
266
         this.callstats = new CallStats(session, settings, this.options);
257
         Statistics.callsStatsInstances.push(this.callstats);
267
         Statistics.callsStatsInstances.push(this.callstats);
268
+        this.callStatsStarted = true;
258
     }
269
     }
259
 };
270
 };
260
 
271
 
262
  * Removes the callstats.io instances.
273
  * Removes the callstats.io instances.
263
  */
274
  */
264
 Statistics.prototype.stopCallStats = function () {
275
 Statistics.prototype.stopCallStats = function () {
265
-    if(this.callstats) {
276
+    if(this.callStatsStarted) {
266
         var index = Statistics.callsStatsInstances.indexOf(this.callstats);
277
         var index = Statistics.callsStatsInstances.indexOf(this.callstats);
267
         if(index > -1)
278
         if(index > -1)
268
             Statistics.callsStatsInstances.splice(index, 1);
279
             Statistics.callsStatsInstances.splice(index, 1);
270
         // feedback even after the conference has been destroyed.
281
         // feedback even after the conference has been destroyed.
271
         // this.callstats = null;
282
         // this.callstats = null;
272
         CallStats.dispose();
283
         CallStats.dispose();
284
+        this.callStatsStarted = false;
273
     }
285
     }
274
 };
286
 };
275
 
287
 

+ 2
- 0
modules/xmpp/strophe.jingle.js Прегледај датотеку

114
                         reasonText = $(iq).find('>jingle>reason>text').text();
114
                         reasonText = $(iq).find('>jingle>reason>text').text();
115
                     }
115
                     }
116
                     this.terminate(sess.sid, reasonCondition, reasonText);
116
                     this.terminate(sess.sid, reasonCondition, reasonText);
117
+                    eventEmitter.emit(XMPPEvents.CALL_ENDED,
118
+                        sess, reasonCondition, reasonText);
117
                     break;
119
                     break;
118
                 case 'transport-replace':
120
                 case 'transport-replace':
119
                     var now = window.performance.now();
121
                     var now = window.performance.now();

+ 5
- 0
service/xmpp/XMPPEvents.js Прегледај датотеку

11
     // Designates an event indicating that an offer (e.g. Jingle
11
     // Designates an event indicating that an offer (e.g. Jingle
12
     // session-initiate) was received.
12
     // session-initiate) was received.
13
     CALL_INCOMING: "xmpp.callincoming.jingle",
13
     CALL_INCOMING: "xmpp.callincoming.jingle",
14
+    // Triggered when Jicofo kills our media session, this can happen while
15
+    // we're still in the MUC, when it decides to terminate the media session.
16
+    // For example when the session is idle for too long, because we're the only
17
+    // person in the conference room.
18
+    CALL_ENDED: "xmpp.callended.jingle",
14
     CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
19
     CHAT_ERROR_RECEIVED: "xmpp.chat_error_received",
15
     CONFERENCE_SETUP_FAILED: "xmpp.conference_setup_failed",
20
     CONFERENCE_SETUP_FAILED: "xmpp.conference_setup_failed",
16
     // Designates an event indicating that the connection to the XMPP server
21
     // Designates an event indicating that the connection to the XMPP server

Loading…
Откажи
Сачувај