我正在开发与Asterisk SIP服务器通信的基于JavaScript的Web SIP客户端。
SIP客户端正在使用JSSIP 3.4.2,我正在Chrome 80版上进行测试。
SIP客户端和SIP服务器都位于防火墙后面。我正在使用STUN服务器 stun.l.google.com:19302 。
呼叫建立良好,但是在调用“ call”方法和建立呼叫(开始RTP会话)之间存在 40秒的延迟。
这是SIP UA注册的代码:
// SIP UA registration
var currentUserSipAccount = {
uri: '211',
pwd: 'secret'
};
var sipDomain = 'sip.my-domain.com';
var sipServerUrl = 'wss://' + sipDomain + ':8089/ws';
var socket = new JsSIP.WebSocketInterface(sipServerUrl);
var connectionParams = {};
connectionParams.sockets = [socket];
connectionParams.register = true;
connectionParams.uri = 'sip:' + currentUserSipAccount.uri + '@' + sipDomain;
connectionParams.password = currentUserSipAccount.pwd;
var bwPhone = new JsSIP.UA(connectionParams);
这是呼叫发起的代码:
// SIP call
var callNumber = 'sip:233@' + sipDomain;
var callOptions = {
mediaConstraints: {
audio: true, // only audio calls
video: false
},
pcConfig: {
iceServers: [
{'urls': ['stun:stun.l.google.com:19302']}
]
}
};
bwPhone.call(callNumber, callOptions);
我已设置每个SIP事件的日志记录,发现延迟与 onicegatheringstatechange 和 onicecandidate 事件有关。
这是Wireshark日志:
每10秒钟发送一个STUN请求,然后立即做出响应。这会发生4次。
这是我得到的浏览器控制台日志:
正在通话的计算机具有多个网络接口。我看到 icecandidate 事件包含两个IP地址,其中一个(169.254.128.100)与以太网相关,未使用,另一个(192.168.1.33)与WiFi相关,用于连接到Internet
我还在浏览器控制台日志中看到,在发起调用后的几毫秒内收到了STUN响应。但是之后,JSSIP等待40秒!
如何避免40秒的延迟?
答案 0 :(得分:4)
收集候选对象可能会很长,通常,当延迟较大时,将找不到最后的候选对象。
为解决延迟,您可以控制超时并在决定时中止。这是jssip超时5秒的示例:
var myCandidateTimeout = null;
_session.on('icecandidate', function(candidate, ready) {
console.log('getting a candidate' + candidate.candidate.candidate);
if (myCandidateTimeout!=null)
clearTimeout(myCandidateTimeout);
// 5 seconds timeout after the last icecandidate received!
myCandidateTimeout = setTimeout(candidate.ready, 5000);
}
答案 1 :(得分:0)
在JSSIP组中获得一些提示。要停止收集ICE候选人并继续SIP流程,我需要在 icecandidate 事件处理程序中调用 event.ready()。
此代码解决了该问题(不确定srflx是什么,也许没有必要):
session.on("icecandidate", function (event) {
if (event.candidate.type === "srflx" &&
event.candidate.relatedAddress !== null &&
event.candidate.relatedPort !== null) {
event.ready();
}
});
答案 2 :(得分:0)
如果您不打算创建电话会议,那么您可以这样做。 (对我有用)
session.on("icecandidate", function (event) {
event.ready();
});