HartleySan
HartleySan

Reputation: 7830

WebRTC: Can't set local description after creating an answer

I'm currently attempting to create a simple video chat service using WebRTC with Ajax for the signalling method.

As per the recommendation of another Stack Overflow user, in order to make sure I was understanding the flow of a standard WebRTC app properly, I first created a simple WebRTC video chat service in which I printed the created offer or answer and ICE candidates out to the screen, and manually copied and pasted that info into a text area in the other client window to process everything. Upon doing that, I was able to successfully get both videos to pop up.

After getting that to work properly, I decided to try and use Ajax as the signalling method. However, I can't seem to get it to work now.

In my current implementation, every time offer/answer or ICE candidate info is created, I instantly create a new Ajax object, which is used to add that info (after the JSON.stringify method has been executed on it) to a DB table. Both clients are constantly polling that DB table, searching for new info from the other client.

I've been echoing a lot of information out to the console, and as far as I can tell, a valid offer is always sent from one client to another, but upon receiving that offer, successfully setting it as the remote description, and creating an answer, any attempts I make to set the local description of the "answerer" fails.

Is there any particular reason why this might happen? Here's a snippet of my code:

var i,
  len;

for (i = 0, len = responseData.length; i < len; i += 1) {

  message = JSON.parse(responseData[i]);

  if (message.type === 'offer') {

    makeAnswer(message);

  }

  // Code omitted,

}

...

makeAnswer = function (offer) {

  pc.setRemoteDescription(new RTCSessionDescription(offer), function () {

    pc.createAnswer(function (desc) {

      // An answer is always properly generated here.

      pc.setLocalDescription(desc, function () {

        // This success callback function is never executed.

        setPayload(JSON.stringify(pc.localDescription));

      }, function () {

        // I always end up here.

      });

    });

  });

};

In essence, I loop through any data retrieved from the DB (sometimes there's both an offer and lots of candidate info that's gathered all at once), and if the type property of a message is 'offer', I call the makeAnswer function, and from there, I set the remote description to the received offer, create an answer, and try to set the answer to the local description, but it always fails at that last step.

If anyone can offer any advice as to why this might be happening, I would be very appreciative.
Thank you very much.

Upvotes: 2

Views: 3533

Answers (1)

HartleySan
HartleySan

Reputation: 7830

Well, I figured out the problem. It turns out that I wasn't encoding the SDP and ICE info before sending it to a PHP script via Ajax. As a result, any plus signs (+) in the SDP/ICE info were being turned into spaces, thus causing the strings to differ between the local and remote clients and not work.

I've always used encodeURIComponent on GET requests with Ajax, but I never knew you had to use that function with POST requests as well. That's good to know.

Anyway, after I started using the encodeURIComponent function with the posted data, and then fixed my logic up a bit so that ICE candidates are never set until after both local and remote descriptions are set, it started working like a charm every time.

That's the good news. The bad news is that everything was working fine on my local host, but as soon as I ported the exact same code over to my web-hosted server, even though the console was reporting that the offer/answer and ICE info were all properly being received and set, the remote video isn't popping up.

Sigh. One more hurdle to cross before I can be done with this.

Anyway, just to let everyone know, the key is to use encodeURIComponent before sending the SDP/ICE info to a server-side script, so that the string received on the other end is exactly the same.

Upvotes: 1

Related Questions