vmayorow
vmayorow

Reputation: 715

A 40 sec delay of SIP call initiation using JSSIP / WebRTC

I am developing a JavaScript-based web SIP client communicating with Asterisk SIP server.

The SIP client is using JSSIP 3.4.2, I'm testing on Chrome version 80.

Both SIP client and SIP server are behind firewalls. I'm using STUN server stun.l.google.com:19302.

The call is established well, but there's a 40 sec delay between calling the "call" method and establishing a call (starting an RTP session).

Here's the code of SIP UA registration:

// 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);

Here's the code of call initiation:

// 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);

I have setup logging of each SIP event and found that the delay is related to the onicegatheringstatechange and onicecandidate events.

Here's the Wireshark log:

enter image description here

Each 10 sec, a STUN request is being sent, followed by an instant response. This happens 4 times.

Here is the browser console log I am getting:

enter image description here

The computer on which I'm doing a call has multiple network interfaces. I see icecandidate events containing two IP addresses, one of them (169.254.128.100) is related to Ethernet and not used, another one (192.168.1.33) is related to WiFi and is used for connecting to Internet.

enter image description here

I also see in the browser console log, that the STUN response is being received within several milliseconds after initiating the call. But after that, JSSIP waits for 40 seconds!

enter image description here

How to avoid this 40 sec delay?

Upvotes: 5

Views: 6261

Answers (5)

iamMAHAM
iamMAHAM

Reputation: 108

In my case

session.on('icecandidate', (e) => {
  console.log(e.candidate.relatedAddress,e.candidate.relatedPort,e.candidate.type); 
  // always return undefined undefined undefined undefined
})

the working version is

const extractValues = (inputString: string) => {
  const match = inputString.match(
    /typ (\w+) raddr (\d+\.\d+\.\d+\.\d+) rport (\d+)/
  );
  if (match) {
    const [, type, raddr, rport] = match;
    return { type, raddr, rport: parseInt(rport, 10) };
  }
  return null;
};

session.on('icecandidate', (e) => {
   const values = extractValues(e.candidate.candidate);
   if (values && values.type === 'srflx' && values.raddr !== 'null' && !isNaN(values.rport)){
     e.ready();
   }
});

Upvotes: 0

mumi
mumi

Reputation: 1

for me defining stun server is solve the problem

Upvotes: 0

Artiom Shelegovich
Artiom Shelegovich

Reputation: 141

If you do not plan to create a conference call, then you can do this. (works for me)

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

Upvotes: 0

vmayorow
vmayorow

Reputation: 715

Got some hints in the JSSIP group. To stop gathering for ICE candidates and continue SIP flow, I need to call event.ready() inside the icecandidate event handler.

This code resolved the issue (not sure what is srflx, maybe that's not necessary):

session.on("icecandidate", function (event) {
    if (event.candidate.type === "srflx" &&
        event.candidate.relatedAddress !== null &&
        event.candidate.relatedPort !== null) {
        event.ready();
    }
});

Upvotes: 2

AymericM
AymericM

Reputation: 1745

Gathering candidates can be very long, and usually, when the delay is large, the last ice candidate will failed to be found.

To solve your delay, your can control the timeout and abort when you decide. This is an example for a timeout of 5 seconds with jssip:

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

Upvotes: 7

Related Questions