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.