What is this data at the end of WebRTC candidate info?

不问归期 提交于 2021-02-08 03:31:51

问题


I set up a basic video chat app using the WebRTC APIs in Chrome along with a WebSocket script I wrote myself following the W3C specs and other questions here on SO.

Sometimes though, when one PC sends ICE candidate info to the other PC via the WebSocket connection, a bunch of garbled text is attached to the end of the JSON-stringified candidate info. This problem only happens sometimes though, and it never happens with the SDP info sent via the createOffer and createAnswer methods.

Please see the following link for an example of what I'm talking about: http://s1290.beta.photobucket.com/user/HartleySan83/media/NGdata_zps0a7203e7.png.html?sort=3&o=0

Because the JSON-stringified candidate info always ends with '}}', by adding an if condition to the WebSocket server script, I was able to circumvent this problem and get the video chat app to work. Unfortunately, this is a hack that I'd like to avoid. Plus, I'd like to know why this is happening in the first place.

It's worth noting that when I either alert or echo the candidate info to the console on the client side before it's sent to the WebSocket server script, none of the extra garbled text is present, so I'm not sure why it's present with the candidate info on the server side and only sometimes.

The following is a code snippet of the client-side code where the candidate info is sent to the server-side script:

function startPeerConnection() {

  navigator.webkitGetUserMedia({ audio: true, video: true }, function (stream) {

    document.getElementById('vid1').src = webkitURL.createObjectURL(stream);

    pc = new webkitRTCPeerConnection(null);

    pc.onicecandidate = function (evt) {

      if (evt.candidate) {

        socket.send(JSON.stringify({ candidate: evt.candidate }));

      }

    };

    pc.onaddstream = function (evt) {

      document.getElementById('vid2').src = webkitURL.createObjectURL(evt.stream);

    };

    pc.addStream(stream);

  }, function () {});

}

And the following is the server-side code that unmasks the received WebSocket data:

$len = ord($buffer[1]) & 127;

if ($len === 126) {

  $masks_start = 4;

} else if ($len === 127) {

  $masks_start = 10;

} else {

  $masks_start = 2;

}

$masks = substr($buffer, $masks_start, 4);

$data = substr($buffer, $masks_start + 4);

$len = strlen($data);

$text = '';

for ($i = 0; $i < $len; $i++) {

  $text .= $data[$i] ^ $masks[$i % 4];

}

if (($end = strpos($text, '}}')) !== false) {
// This if condition eliminates the garbled text.
// Without it, a "Could not decode a text frame as UTF-8"
// error is output to the Chrome console.

  $text = substr($text, 0, $end + 2);

  $len = strlen($text);

}

if ($len <= 125) {

  $header = pack('C*', 129, $len);

} else if (($len > 125) && ($len < 65536)) {

  $header = pack('C*', 129, 126, ($len >> 8) & 255, $len & 255);

} else if ($len >= 65536) {

  $header = pack('C*', 129, 127, ($len >> 56) & 255, ($len >> 48) & 255, ($len >> 40) & 255, ($len >> 32) & 255, ($len >> 24) & 255, ($len >> 16) & 255, ($len >> 8) & 255, $len & 255);

}

$server_response = $header . $text;

foreach ($users as $user) {

  if ($user !== $users[$user_idx]) {

    @socket_write($user['socket'], $server_response, strlen($server_response));

  }

}

I've searched high and low on the Internet for anyone else with the same problem, but I can't find anyone or anything in the specs that talks about this, so I imagine it's some problem with my code.

Any guidance that anyone can offer as to the source of the problem would be much appreciated. Thank you.


回答1:


Well, I finally found the problem. My server-side WebSocket code was indeed wrong. The problem was that I was miscalculating the length. I, unfortunately, was relying on some page I found about WebSockets in PHP, and as it turns out, the page had a number of errors in its code, which I slowly started to realize more and more. Anyway, here's the proper way to calculate the length of messages sent from a client to the server:

$len = ord($buffer[1]) & 127; // This is the default payload length.

if ($len === 126) { // If 126, then need to use the payload length at the 3rd and 4th bytes.

  $masks_start = 4;

  $len = (ord($buffer[2]) << 8) + ord($buffer[3]);

} else if ($len === 127) { // If 127, then need to use the next 8 bytes to calculate the length.

  $masks_start = 10;

  $len = (ord($buffer[2]) << 56) + (ord($buffer[3]) << 48) + (ord($buffer[4]) << 40) + (ord($buffer[5]) << 32) + (ord($buffer[6]) << 24) + (ord($buffer[7]) << 16) + (ord($buffer[8]) << 8) + ord($buffer[9]);

} else { // Otherwise, the default payload length is correct.

  $masks_start = 2;

}

After doing that, everything worked great. Well, I'm still haven't figured out how to properly close a WebSocket connection, but other than that, the WebRTC video is working great.




回答2:


Is the garbled binary data being added by client1 before it sends it to the Websocket server? Or are you only seeing it on the client2 after it's been processed by the websocket server? I ask because I ran into a similar problem where my signaling server (SignalR in this case) had a bug that corrupted the SDP I was sending in-between PeerConnections.



来源:https://stackoverflow.com/questions/14425382/what-is-this-data-at-the-end-of-webrtc-candidate-info

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!