【问题标题】:A 40 sec delay of SIP call initiation using JSSIP / WebRTC使用 JSSIP / WebRTC 发起 SIP 呼叫的 40 秒延迟
【发布时间】:2020-04-16 14:54:17
【问题描述】:

我正在开发一个基于 JavaScript 的 Web SIP 客户端与 Asterisk 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 事件的日志记录,发现延迟与 onicegatheringstatechangeonicecandidate 事件有关。

这是 Wireshark 日志:

每 10 秒发送一次 STUN 请求,然后是即时响应。这种情况发生了 4 次。

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

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

我还在浏览器控制台日志中看到,在启动呼叫后的几毫秒内收到了 STUN 响应。但在那之后,JSSIP 会等待 40 秒!

如何避免这 40 秒的延迟?

【问题讨论】:

    标签: javascript webrtc sip voip jssip


    【解决方案1】:

    收集候选人可能会很长,而且通常当延迟很大时,最后一个冰候选人会找不到。

    为了解决您的延迟问题,您可以控制超时并在您决定时中止。这是一个使用 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);
    }
    

    【讨论】:

      【解决方案2】:

      在 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();
          }
      });
      

      【讨论】:

      • 我更喜欢我提供的代码解决方案,因为可能会出现几个“srflx”。您也可以结合一个解决方案,在获得至少一个 srflx 候选人后才开始超时。更小的超时可能会更好......
      【解决方案3】:

      如果您不打算创建电话会议,那么您可以这样做。 (为我工作)

      session.on("icecandidate", function (event) {
         event.ready();
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-20
        • 1970-01-01
        相关资源
        最近更新 更多