@@ -42,6 +42,8 @@ JsSIP.UA = function(configuration) {
42
42
ict : { }
43
43
} ;
44
44
45
+ this . transportRecoverAttempts = 0 ;
46
+
45
47
/**
46
48
* Load configuration
47
49
*
@@ -61,17 +63,6 @@ JsSIP.UA.prototype = new JsSIP.EventEmitter();
61
63
// High Level API
62
64
//=================
63
65
64
- /**
65
- * Notify the UA about network availability.
66
- */
67
- JsSIP . UA . prototype . networkIsReady = function ( ) {
68
- console . log ( 'Network Ready notification received' ) ;
69
- // Stablish connection if needed.
70
- if ( this . status === JsSIP . c . UA_STATUS_NOT_READY && this . error === JsSIP . c . UA_NETWORK_ERROR ) {
71
- this . transport . connect ( ) ;
72
- }
73
- } ;
74
-
75
66
/**
76
67
* Register.
77
68
*
@@ -316,9 +307,14 @@ JsSIP.UA.prototype.onTransportError = function(transport) {
316
307
new JsSIP . Transport ( this , server ) ;
317
308
} else {
318
309
this . closeSessionsOnTransportError ( ) ;
319
- this . status = JsSIP . c . UA_STATUS_NOT_READY ;
320
- this . error = JsSIP . c . UA_NETWORK_ERROR ;
321
- this . emit ( 'disconnected' ) ;
310
+ if ( ! this . error || this . error !== JsSIP . c . UA_NETWORK_ERROR ) {
311
+ this . status = JsSIP . c . UA_STATUS_NOT_READY ;
312
+ this . error = JsSIP . c . UA_NETWORK_ERROR ;
313
+ this . emit ( 'disconnected' ) ;
314
+ }
315
+
316
+ // Transport Recovery process
317
+ this . recoverTransport ( ) ;
322
318
}
323
319
} ;
324
320
@@ -331,6 +327,9 @@ JsSIP.UA.prototype.onTransportError = function(transport) {
331
327
JsSIP . UA . prototype . onTransportConnected = function ( transport ) {
332
328
this . transport = transport ;
333
329
330
+ // Reset transport recovery counter
331
+ this . transportRecoverAttempts = 0 ;
332
+
334
333
transport . server . status = JsSIP . c . WS_SERVER_READY ;
335
334
console . log ( JsSIP . c . LOG_UA + 'connection status set to: ' + JsSIP . c . WS_SERVER_READY ) ;
336
335
@@ -569,6 +568,36 @@ JsSIP.UA.prototype.closeSessionsOnTransportError = function() {
569
568
}
570
569
} ;
571
570
571
+ JsSIP . UA . prototype . recoverTransport = function ( ua ) {
572
+ var idx , k , nextRetry , count , server ;
573
+
574
+ ua = ua || this ;
575
+ count = ua . transportRecoverAttempts ;
576
+
577
+ for ( idx in ua . configuration . outbound_proxy_set ) {
578
+ ua . configuration . outbound_proxy_set [ idx ] . status = 0 ;
579
+ }
580
+
581
+ server = ua . getNextWsServer ( ) ;
582
+
583
+ k = Math . floor ( ( Math . random ( ) * Math . pow ( 2 , count ) ) + 1 ) ;
584
+ nextRetry = k * ua . configuration . connection_recovery_min_interval ;
585
+
586
+ if ( nextRetry > ua . configuration . connection_recovery_max_interval ) {
587
+ console . log ( JsSIP . c . LOG_UA + 'Time for next connection attempt exceeds connection_recovery_max_interval. Resetting counter' ) ;
588
+ nextRetry = ua . configuration . connection_recovery_min_interval ;
589
+ count = 0 ;
590
+ }
591
+
592
+ console . log ( JsSIP . c . LOG_UA + 'Next connection attempt in: ' + nextRetry + ' seconds' ) ;
593
+
594
+ window . setTimeout (
595
+ function ( ) {
596
+ ua . transportRecoverAttempts = count + 1 ;
597
+ new JsSIP . Transport ( ua , server ) ;
598
+ } , nextRetry * 1000 ) ;
599
+ } ;
600
+
572
601
/**
573
602
* Configuration load.
574
603
* @private
@@ -592,8 +621,11 @@ JsSIP.UA.prototype.loadConfig = function(configuration) {
592
621
register : true ,
593
622
594
623
// Transport related parameters
595
- max_reconnection : 3 ,
596
- reconnection_timeout : 4 ,
624
+ ws_server_max_reconnection : 3 ,
625
+ ws_server_reconnection_timeout : 4 ,
626
+
627
+ connection_recovery_min_interval : 2 ,
628
+ connection_recovery_max_interval : 30 ,
597
629
598
630
// Session parameters
599
631
no_answer_timeout : 60 ,
@@ -654,6 +686,14 @@ JsSIP.UA.prototype.loadConfig = function(configuration) {
654
686
}
655
687
}
656
688
689
+ // Sanity Checks
690
+
691
+ // Connection recovery intervals
692
+ if ( settings . connection_recovery_max_interval < settings . connection_recovery_min_interval ) {
693
+ console . error ( '"connection_recovery_max_interval" parameter is lower than "connection_recovery_min_interval"' ) ;
694
+ return false ;
695
+ }
696
+
657
697
// Post Configuration Process
658
698
659
699
// Instance-id for GRUU
@@ -731,9 +771,13 @@ JsSIP.UA.configuration_skeleton = (function() {
731
771
// Internal parameters
732
772
"instance_id" ,
733
773
"jssip_id" ,
734
- "max_reconnection" ,
735
774
736
- "reconnection_timeout" ,
775
+ "ws_server_max_reconnection" ,
776
+ "ws_server_reconnection_timeout" ,
777
+
778
+ "connection_recovery_min_interval" ,
779
+ "connection_recovery_max_interval" ,
780
+
737
781
"register_min_expires" ,
738
782
739
783
// Mandatory user configurable parameters
@@ -894,6 +938,24 @@ JsSIP.UA.configuration_check = {
894
938
return true ;
895
939
}
896
940
} ,
941
+ connection_recovery_min_interval : function ( connection_recovery_min_interval ) {
942
+ if ( ! Number ( connection_recovery_min_interval ) ) {
943
+ return false ;
944
+ } else if ( connection_recovery_min_interval < 0 ) {
945
+ return false ;
946
+ } else {
947
+ return true ;
948
+ }
949
+ } ,
950
+ connection_recovery_max_interval : function ( connection_recovery_max_interval ) {
951
+ if ( ! Number ( connection_recovery_max_interval ) ) {
952
+ return false ;
953
+ } else if ( connection_recovery_max_interval < 0 ) {
954
+ return false ;
955
+ } else {
956
+ return true ;
957
+ }
958
+ } ,
897
959
hack_via_tcp : function ( hack_via_tcp ) {
898
960
if ( typeof hack_via_tcp !== 'boolean' ) {
899
961
return false ;
0 commit comments