@@ -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
@@ -1136,27 +1136,38 @@ export class WebRTCAdaptor {
1136
1136
1137
1137
this . remotePeerConnection [ streamId ] . oniceconnectionstatechange = event => {
1138
1138
var obj = { state : this . remotePeerConnection [ streamId ] . iceConnectionState , streamId : streamId } ;
1139
- if ( obj . state == "failed" || obj . state == "disconnected" || obj . state == "closed" ) {
1140
- this . reconnectIfRequired ( 3000 ) ;
1141
- }
1142
- this . notifyEventListeners ( "ice_connection_state_changed" , obj ) ;
1143
-
1144
- //
1145
- if ( ! this . isPlayMode && ! this . playStreamId . includes ( streamId ) ) {
1146
- if ( this . remotePeerConnection [ streamId ] . iceConnectionState == "connected" ) {
1147
1139
1148
- this . mediaManager . changeBandwidth ( this . mediaManager . bandwidth , streamId ) . then ( ( ) => {
1149
- Logger . debug ( "Bandwidth is changed to " + this . mediaManager . bandwidth ) ;
1150
- } )
1151
- . catch ( e => Logger . warn ( e ) ) ;
1152
- }
1153
- }
1140
+ this . oniceconnectionstatechangeCallback ( obj ) ;
1154
1141
}
1155
1142
1156
1143
}
1157
1144
1158
1145
return this . remotePeerConnection [ streamId ] ;
1159
1146
}
1147
+
1148
+ oniceconnectionstatechangeCallback ( obj )
1149
+ {
1150
+ Logger . debug ( "ice connection state is " + obj . state + " for streamId: " + obj . streamId ) ;
1151
+ if ( obj . state == "failed" || obj . state == "disconnected" || obj . state == "closed" ) {
1152
+ //try immediately
1153
+ Logger . debug ( "ice connection state is failed, disconnected or closed for streamId: " + obj . streamId + " it will try to reconnect immediately" ) ;
1154
+ this . reconnectIfRequired ( 0 , false ) ;
1155
+ }
1156
+ this . notifyEventListeners ( "ice_connection_state_changed" , obj ) ;
1157
+
1158
+ //
1159
+ if ( ! this . isPlayMode && ! this . playStreamId . includes ( obj . streamId ) ) {
1160
+ if ( this . remotePeerConnection [ obj . streamId ] != null && this . remotePeerConnection [ obj . streamId ] . iceConnectionState == "connected" ) {
1161
+
1162
+ this . mediaManager . changeBandwidth ( this . mediaManager . bandwidth , obj . streamId ) . then ( ( ) => {
1163
+ Logger . debug ( "Bandwidth is changed to " + this . mediaManager . bandwidth ) ;
1164
+ } )
1165
+ . catch ( e => Logger . warn ( e ) ) ;
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+
1160
1171
1161
1172
/**
1162
1173
* Called internally to close PeerConnection.
@@ -1745,10 +1756,7 @@ export class WebRTCAdaptor {
1745
1756
websocket_url : this . websocketURL ,
1746
1757
webrtcadaptor : this ,
1747
1758
callback : ( info , obj ) => {
1748
- if ( info == "closed" ) {
1749
- this . reconnectIfRequired ( ) ;
1750
- }
1751
- this . notifyEventListeners ( info , obj ) ;
1759
+ this . websocketCallback ( info , obj )
1752
1760
} ,
1753
1761
callbackError : ( error , message ) => {
1754
1762
this . notifyErrorEventListeners ( error , message )
@@ -1757,6 +1765,22 @@ export class WebRTCAdaptor {
1757
1765
} ) ;
1758
1766
}
1759
1767
}
1768
+
1769
+ websocketCallback ( info , obj ) {
1770
+
1771
+ if ( info == "closed" || info == "server_will_stop" ) {
1772
+ Logger . info ( "Critical response from server:" + info + ". It will reconnect immediately if there is an active connection" ) ;
1773
+
1774
+ //close websocket reconnect again
1775
+ if ( info == "server_will_stop" ) {
1776
+ this . webSocketAdaptor . close ( ) ;
1777
+ }
1778
+ //try with forcing reconnect because webrtc will be closed as well
1779
+ this . reconnectIfRequired ( 0 , true ) ;
1780
+ }
1781
+
1782
+ this . notifyEventListeners ( info , obj ) ;
1783
+ }
1760
1784
1761
1785
/**
1762
1786
* Called to stop Web Socket connection
0 commit comments