@@ -358,6 +358,11 @@ export class WebRTCAdaptor {
358
358
* This is the time info for the last reconnection attempt
359
359
*/
360
360
this . lastReconnectiontionTrialTime = 0 ;
361
+
362
+ /**
363
+ * TimerId for the pending try again call
364
+ */
365
+ this . pendingTryAgainTimerId = - 1 ;
361
366
362
367
/**
363
368
* All media management works for teh local stream are made by @MediaManager class.
@@ -516,15 +521,8 @@ export class WebRTCAdaptor {
516
521
}
517
522
//init peer connection for reconnectIfRequired
518
523
this . initPeerConnection ( streamId , "publish" ) ;
519
- setTimeout ( ( ) => {
520
- //check if it is connected or not
521
- //this resolves if the server responds with some error message
522
- if ( this . iceConnectionState ( this . publishStreamId ) != "checking" && this . iceConnectionState ( this . publishStreamId ) != "connected" && this . iceConnectionState ( this . publishStreamId ) != "completed" ) {
523
- //if it is not connected, try to reconnect
524
- this . reconnectIfRequired ( 0 ) ;
525
- }
526
- } , 3000 ) ;
527
-
524
+
525
+ this . reconnectIfRequired ( 3000 , false ) ;
528
526
}
529
527
530
528
sendPublishCommand ( streamId , token , subscriberId , subscriberCode , streamName , mainTrack , metaData , role , videoEnabled , audioEnabled ) {
@@ -605,43 +603,44 @@ export class WebRTCAdaptor {
605
603
606
604
//init peer connection for reconnectIfRequired
607
605
this . initPeerConnection ( streamId , "play" ) ;
608
-
609
- setTimeout ( ( ) => {
610
- //check if it is connected or not
611
- //this resolves if the server responds with some error message
612
- if ( this . iceConnectionState ( streamId ) != "checking" &&
613
- this . iceConnectionState ( streamId ) != "connected" &&
614
- this . iceConnectionState ( streamId ) != "completed" ) {
615
- //if it is not connected, try to reconnect
616
- this . reconnectIfRequired ( 0 ) ;
617
- }
618
- } , 3000 ) ;
606
+ this . reconnectIfRequired ( 3000 , false ) ;
619
607
}
620
608
621
609
/**
622
610
* Reconnects to the stream if it is not stopped on purpose
623
611
* @param {number } [delayMs]
624
612
* @returns
625
613
*/
626
- reconnectIfRequired ( delayMs = 3000 ) {
614
+ reconnectIfRequired ( delayMs = 3000 , forceReconnect = false ) {
627
615
if ( this . reconnectIfRequiredFlag ) {
628
- //It's important to run the following methods after 3000 ms because the stream may be stopped by the user in the meantime
629
- if ( delayMs > 0 ) {
630
- setTimeout ( ( ) => {
631
- this . tryAgain ( ) ;
632
- } , delayMs ) ;
616
+ if ( delayMs <= 0 ) {
617
+ delayMs = 500 ;
618
+ //clear the timer because there is a demand to reconnect without delay
619
+ clearTimeout ( this . pendingTryAgainTimerId ) ;
620
+ this . pendingTryAgainTimerId = - 1 ;
633
621
}
634
- else {
635
- this . tryAgain ( )
622
+
623
+ if ( this . pendingTryAgainTimerId == - 1 )
624
+ {
625
+ this . pendingTryAgainTimerId = setTimeout ( ( ) =>
626
+ {
627
+ this . pendingTryAgainTimerId = - 1 ;
628
+ this . tryAgain ( forceReconnect ) ;
629
+ } ,
630
+ delayMs ) ;
636
631
}
637
632
}
638
633
}
639
634
640
- tryAgain ( ) {
635
+ tryAgain ( forceReconnect ) {
641
636
642
637
const now = Date . now ( ) ;
643
638
//to prevent too many trial from different paths
644
- if ( now - this . lastReconnectiontionTrialTime < 3000 ) {
639
+ const timeDiff = now - this . lastReconnectiontionTrialTime ; ;
640
+ if ( timeDiff < 3000 && forceReconnect == false ) {
641
+ //check again 1 seconds later if it is not stopped on purpose
642
+ Logger . debug ( "Reconnection request received after " + timeDiff + " ms. It should be at least 3000ms. It will try again after 1000ms" ) ;
643
+ this . reconnectIfRequired ( 1000 , forceReconnect ) ;
645
644
return ;
646
645
}
647
646
this . lastReconnectiontionTrialTime = now ;
@@ -650,10 +649,10 @@ export class WebRTCAdaptor {
650
649
//if remotePeerConnection has a peer connection for the stream id, it means that it is not stopped on purpose
651
650
652
651
if ( this . remotePeerConnection [ this . publishStreamId ] != null &&
652
+ ( forceReconnect ||
653
653
//check connection status to not stop streaming an active stream
654
- this . iceConnectionState ( this . publishStreamId ) != "checking" &&
655
- this . iceConnectionState ( this . publishStreamId ) != "connected" &&
656
- this . iceConnectionState ( this . publishStreamId ) != "completed" ) {
654
+ [ "checking" , "connected" , "completed" ] . indexOf ( this . iceConnectionState ( this . publishStreamId ) ) === - 1 )
655
+ ) {
657
656
// notify that reconnection process started for publish
658
657
this . notifyEventListeners ( "reconnection_attempt_for_publisher" , this . publishStreamId ) ;
659
658
@@ -669,11 +668,12 @@ export class WebRTCAdaptor {
669
668
//reconnect play
670
669
for ( var index in this . playStreamId ) {
671
670
let streamId = this . playStreamId [ index ] ;
672
- if ( this . remotePeerConnection [ streamId ] != "null" &&
673
- //check connection status to not stop streaming an active stream
674
- this . iceConnectionState ( streamId ) != "checking" &&
675
- this . iceConnectionState ( streamId ) != "connected" &&
676
- this . iceConnectionState ( streamId ) != "completed" ) {
671
+ if ( this . remotePeerConnection [ streamId ] != null &&
672
+ ( forceReconnect ||
673
+ //check connection status to not stop streaming an active stream
674
+ [ "checking" , "connected" , "completed" ] . indexOf ( this . iceConnectionState ( streamId ) ) === - 1
675
+ )
676
+ ) {
677
677
// notify that reconnection process started for play
678
678
this . notifyEventListeners ( "reconnection_attempt_for_player" , streamId ) ;
679
679
@@ -1152,27 +1152,38 @@ export class WebRTCAdaptor {
1152
1152
1153
1153
this . remotePeerConnection [ streamId ] . oniceconnectionstatechange = event => {
1154
1154
var obj = { state : this . remotePeerConnection [ streamId ] . iceConnectionState , streamId : streamId } ;
1155
- if ( obj . state == "failed" || obj . state == "disconnected" || obj . state == "closed" ) {
1156
- this . reconnectIfRequired ( 3000 ) ;
1157
- }
1158
- this . notifyEventListeners ( "ice_connection_state_changed" , obj ) ;
1159
-
1160
- //
1161
- if ( ! this . isPlayMode && ! this . playStreamId . includes ( streamId ) ) {
1162
- if ( this . remotePeerConnection [ streamId ] . iceConnectionState == "connected" ) {
1163
1155
1164
- this . mediaManager . changeBandwidth ( this . mediaManager . bandwidth , streamId ) . then ( ( ) => {
1165
- Logger . debug ( "Bandwidth is changed to " + this . mediaManager . bandwidth ) ;
1166
- } )
1167
- . catch ( e => Logger . warn ( e ) ) ;
1168
- }
1169
- }
1156
+ this . oniceconnectionstatechangeCallback ( obj ) ;
1170
1157
}
1171
1158
1172
1159
}
1173
1160
1174
1161
return this . remotePeerConnection [ streamId ] ;
1175
1162
}
1163
+
1164
+ oniceconnectionstatechangeCallback ( obj )
1165
+ {
1166
+ Logger . debug ( "ice connection state is " + obj . state + " for streamId: " + obj . streamId ) ;
1167
+ if ( obj . state == "failed" || obj . state == "disconnected" || obj . state == "closed" ) {
1168
+ //try immediately
1169
+ Logger . debug ( "ice connection state is failed, disconnected or closed for streamId: " + obj . streamId + " it will try to reconnect immediately" ) ;
1170
+ this . reconnectIfRequired ( 0 , false ) ;
1171
+ }
1172
+ this . notifyEventListeners ( "ice_connection_state_changed" , obj ) ;
1173
+
1174
+ //
1175
+ if ( ! this . isPlayMode && ! this . playStreamId . includes ( obj . streamId ) ) {
1176
+ if ( this . remotePeerConnection [ obj . streamId ] != null && this . remotePeerConnection [ obj . streamId ] . iceConnectionState == "connected" ) {
1177
+
1178
+ this . mediaManager . changeBandwidth ( this . mediaManager . bandwidth , obj . streamId ) . then ( ( ) => {
1179
+ Logger . debug ( "Bandwidth is changed to " + this . mediaManager . bandwidth ) ;
1180
+ } )
1181
+ . catch ( e => Logger . warn ( e ) ) ;
1182
+ }
1183
+ }
1184
+ }
1185
+
1186
+
1176
1187
1177
1188
/**
1178
1189
* Called internally to close PeerConnection.
@@ -1761,10 +1772,7 @@ export class WebRTCAdaptor {
1761
1772
websocket_url : this . websocketURL ,
1762
1773
webrtcadaptor : this ,
1763
1774
callback : ( info , obj ) => {
1764
- if ( info == "closed" ) {
1765
- this . reconnectIfRequired ( ) ;
1766
- }
1767
- this . notifyEventListeners ( info , obj ) ;
1775
+ this . websocketCallback ( info , obj )
1768
1776
} ,
1769
1777
callbackError : ( error , message ) => {
1770
1778
this . notifyErrorEventListeners ( error , message )
@@ -1773,6 +1781,22 @@ export class WebRTCAdaptor {
1773
1781
} ) ;
1774
1782
}
1775
1783
}
1784
+
1785
+ websocketCallback ( info , obj ) {
1786
+
1787
+ if ( info == "closed" || info == "server_will_stop" ) {
1788
+ Logger . info ( "Critical response from server:" + info + ". It will reconnect immediately if there is an active connection" ) ;
1789
+
1790
+ //close websocket reconnect again
1791
+ if ( info == "server_will_stop" ) {
1792
+ this . webSocketAdaptor . close ( ) ;
1793
+ }
1794
+ //try with forcing reconnect because webrtc will be closed as well
1795
+ this . reconnectIfRequired ( 0 , true ) ;
1796
+ }
1797
+
1798
+ this . notifyEventListeners ( info , obj ) ;
1799
+ }
1776
1800
1777
1801
/**
1778
1802
* Called to stop Web Socket connection
0 commit comments