Skip to content

Commit bbee4ea

Browse files
committed
Merge pull request #190 from markandrus/crlf-keep-alive
Expand keep-alive support
2 parents 4f8d2dc + dac3c42 commit bbee4ea

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

src/Transport.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ Transport = function(ua, server) {
3030
this.reconnectTimer = null;
3131
this.lastTransportError = {};
3232

33+
this.keepAliveInterval = ua.configuration.keepAliveInterval;
34+
this.keepAliveTimer = null;
35+
3336
this.ua.transport = this;
3437

3538
// Connect
@@ -57,6 +60,38 @@ Transport.prototype = {
5760
}
5861
},
5962

63+
/**
64+
* Send a keep-alive (a double-CRLF sequence).
65+
* @private
66+
* @returns {Boolean}
67+
*/
68+
sendKeepAlive: function() {
69+
return this.send('\r\n\r\n');
70+
},
71+
72+
/**
73+
* Start sending keep-alives.
74+
* @private
75+
*/
76+
startSendingKeepAlives: function() {
77+
if (this.keepAliveInterval && !this.keepAliveTimer) {
78+
this.keepAliveTimer = SIP.Timers.setTimeout(function() {
79+
this.sendKeepAlive();
80+
this.keepAliveTimer = null;
81+
this.startSendingKeepAlives();
82+
}.bind(this), computeKeepAliveTimeout(this.keepAliveInterval));
83+
}
84+
},
85+
86+
/**
87+
* Stop sending keep-alives.
88+
* @private
89+
*/
90+
stopSendingKeepAlives: function() {
91+
SIP.Timers.clearTimeout(this.keepAliveTimer);
92+
this.keepAliveTimer = null;
93+
},
94+
6095
/**
6196
* Disconnect socket.
6297
*/
@@ -65,6 +100,8 @@ Transport.prototype = {
65100
// Clear reconnectTimer
66101
SIP.Timers.clearTimeout(this.reconnectTimer);
67102

103+
this.stopSendingKeepAlives();
104+
68105
this.closed = true;
69106
this.logger.log('closing WebSocket ' + this.server.ws_uri);
70107
this.ws.close();
@@ -146,6 +183,8 @@ Transport.prototype = {
146183
this.closed = false;
147184
// Trigger onTransportConnected callback
148185
this.ua.onTransportConnected(this);
186+
// Start sending keep-alives
187+
this.startSendingKeepAlives();
149188
},
150189

151190
/**
@@ -158,6 +197,8 @@ Transport.prototype = {
158197
this.lastTransportError.code = e.code;
159198
this.lastTransportError.reason = e.reason;
160199

200+
this.stopSendingKeepAlives();
201+
161202
if (this.reconnection_attempts > 0) {
162203
this.logger.log('Reconnection attempt ' + this.reconnection_attempts + ' failed (code: ' + e.code + (e.reason? '| reason: ' + e.reason : '') +')');
163204
this.reconnect();
@@ -302,6 +343,16 @@ Transport.prototype = {
302343
}
303344
};
304345

346+
/**
347+
* Compute an amount of time in seconds to wait before sending another
348+
* keep-alive.
349+
* @returns {Number}
350+
*/
351+
function computeKeepAliveTimeout(upperBound) {
352+
var lowerBound = upperBound * 0.8;
353+
return 1000 * (Math.random() * (upperBound - lowerBound) + lowerBound);
354+
}
355+
305356
Transport.C = C;
306357
return Transport;
307358
};

src/UA.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,8 @@ UA.prototype.loadConfig = function(configuration) {
884884
connectionRecoveryMinInterval: 2,
885885
connectionRecoveryMaxInterval: 30,
886886

887+
keepAliveInterval: 0,
888+
887889
usePreloadedRoute: false,
888890

889891
//string to be inserted into User-Agent request header
@@ -1114,6 +1116,7 @@ UA.configuration_skeleton = (function() {
11141116
"authorizationUser",
11151117
"connectionRecoveryMaxInterval",
11161118
"connectionRecoveryMinInterval",
1119+
"keepAliveInterval",
11171120
"displayName",
11181121
"hackViaTcp", // false.
11191122
"hackIpInContact", //false
@@ -1326,6 +1329,16 @@ UA.configuration_check = {
13261329
}
13271330
},
13281331

1332+
keepAliveInterval: function(keepAliveInterval) {
1333+
var value;
1334+
if (SIP.Utils.isDecimal(keepAliveInterval)) {
1335+
value = Number(keepAliveInterval);
1336+
if (value > 0) {
1337+
return value;
1338+
}
1339+
}
1340+
},
1341+
13291342
noAnswerTimeout: function(noAnswerTimeout) {
13301343
var value;
13311344
if (SIP.Utils.isDecimal(noAnswerTimeout)) {

0 commit comments

Comments
 (0)