使用JSSIP / WebRTC的SIP呼叫发起延迟40秒

时间:2020-04-16 14:54:17

标签: javascript webrtc sip voip jssip

我正在开发与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日志:

enter image description here

每10秒钟发送一个STUN请求,然后立即做出响应。这会发生4次。

这是我得到的浏览器控制台日志:

enter image description here

正在通话的计算机具有多个网络接口。我看到 icecandidate 事件包含两个IP地址,其中一个(169.254.128.100)与以太网相关,未使用,另一个(192.168.1.33)与WiFi相关,用于连接到Internet

enter image description here

我还在浏览器控制台日志中看到,在发起调用后的几毫秒内收到了STUN响应。但是之后,JSSIP等待40秒!

enter image description here

如何避免40秒的延迟?

3 个答案:

答案 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();
});
相关问题