Что это за данные в конце информации о кандидате WebRTC?

Я настроил базовое приложение для видеочата, используя API-интерфейсы WebRTC в Chrome вместе со сценарием WebSocket, который я написал сам в соответствии со спецификациями W3C и другими вопросами здесь, на SO.

Однако иногда, когда один компьютер отправляет информацию о кандидате ICE на другой компьютер через соединение WebSocket, к концу информации о кандидате в формате JSON прикрепляется куча искаженного текста. Однако эта проблема возникает только иногда и никогда не возникает с информацией SDP, отправляемой с помощью методов createOffer и createAnswer.

Пожалуйста, посмотрите следующую ссылку для примера того, о чем я говорю: http://s1290.beta.photobucket.com/user/HartleySan83/media/NGdata_zps0a7203e7.png.html?sort=3&o=0

Поскольку информация о кандидате в формате JSON всегда заканчивается на «}}», добавив условие if в сценарий сервера WebSocket, я смог обойти эту проблему и заставить приложение видеочата работать. К сожалению, это взлом, которого я хотел бы избежать. Кроме того, я хотел бы знать, почему это происходит в первую очередь.

Стоит отметить, что когда я либо предупреждаю, либо вывожу информацию о кандидате на консоль на стороне клиента, прежде чем она будет отправлена ​​серверному сценарию WebSocket, никакого лишнего искаженного текста нет, поэтому я не уверен, почему он присутствует с кандидатом информация на стороне сервера и только иногда.

Ниже приведен фрагмент кода на стороне клиента, в котором информация о кандидате отправляется сценарию на стороне сервера:

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

}

И следующий код на стороне сервера, который демаскирует полученные данные WebSocket:

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

  }

}

Я искал в Интернете всех, у кого была такая же проблема, но я не могу найти никого или ничего в спецификациях, где говорится об этом, поэтому я предполагаю, что это какая-то проблема с моим кодом.

Любое руководство, которое кто-либо может предложить относительно источника проблемы, будет высоко оценено. Спасибо.


person HartleySan    schedule 20.01.2013    source источник
comment
выглядит как некоторые двоичные данные. в любом случае, эта информация необходима, чтобы сообщить удаленному узлу, как установить соединение с локальным узлом или наоборот.   -  person Yury Solovyov    schedule 20.01.2013
comment
Я не думаю, что бинарные данные нужны, потому что когда я просто обрезаю все после символов '}}' (т.е. когда я избавляюсь от всех бинарных данных), то все проходит нормально и удаленное видео мгновенно выскакивает с обоих концов и работает нормально. Я продолжу изучение вопроса.   -  person HartleySan    schedule 21.01.2013


Ответы (2)


Ну наконец-то нашел проблему. Мой код WebSocket на стороне сервера действительно был неправильным. Проблема была в том, что я неправильно рассчитал длину. Я, к сожалению, полагался на какую-то страницу, которую я нашел о WebSockets в PHP, и, как оказалось, на странице было несколько ошибок в коде, которые я постепенно начал осознавать все больше и больше. Во всяком случае, вот правильный способ расчета длины сообщений, отправляемых клиентом на сервер:

$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;

}

После этого все заработало отлично. Что ж, я до сих пор не понял, как правильно закрыть соединение WebSocket, но в остальном видео WebRTC работает отлично.

person HartleySan    schedule 23.01.2013

Добавляются ли искаженные двоичные данные клиентом1 перед отправкой на сервер Websocket? Или вы видите его только на клиенте 2 после того, как он был обработан сервером веб-сокетов? Я спрашиваю, потому что столкнулся с похожей проблемой, когда моя сигнализация сервер (в данном случае SignalR) имел ошибку, которая повредила SDP, который я отправлял между PeerConnections.

person Ken Smith    schedule 22.01.2013
comment
Я не уверен, но я думаю, что искаженный текст добавляется сервером/соединением WebSocket. Ниже приведен снимок экрана с выводом консоли командной строки, сгенерированным сценарием сервера, и выводом строк на консоль JS в Chrome непосредственно перед отправкой строк сценарию сервера WebSocket: s172.beta.photobucket.com/user/HartleySan/media/ Как видите, никаких дополнительных данные выводятся на консоль Chrome, поэтому я должен предположить, что они добавляются сценарием сервера и/или соединением. Тоже бывает только иногда. - person HartleySan; 22.01.2013
comment
Кроме того, я не использую сторонний скрипт. Весь мой код — это код, который я написал сам на основе информации, полученной из спецификаций WebRTC/WebSocket и других ответов здесь, на SO. Таким образом, я думаю, что понимаю все, что происходит в моих сценариях, но, очевидно, нет, так как что-то иногда вызывает создание этого искаженного текста. - person HartleySan; 22.01.2013
comment
Еще одна вещь: я выполнил поиск сообщения «Не удалось декодировать текстовый фрейм как сообщение UTF-8» и нашел следующую статью, которая, похоже, связана с моей проблемой: blog.fgribreau.com/2012/05/ Парень рекомендует два метода для что делать с этим: 1) Обрезать строку (как я делаю сейчас; это работает, но я бы хотел этого избежать, если это возможно). 2) Используйте функции escape/unescape и encodeURIComponent/decodeURIComponent в JS. Я бы предпочел использовать метод № 2, но когда я пытаюсь, это ничего не меняет. - person HartleySan; 22.01.2013
comment
Это определенно звучит так, как будто это ваша реализация веб-сокета (будь то на клиенте или сервере), которая вызывает у вас горе. Единственный совет, который я бы дал, это отметить, что веб-сокеты — это довольно низкоуровневый протокол, и что существует множество библиотек (как на сервере, так и на клиенте), которые абстрагируют многие из этих низкоуровневых протоколов. Детали. Возможно, стоит изучить их, хотя бы для того, чтобы посмотреть, как они справляются с кодировкой. - person Ken Smith; 22.01.2013
comment
Да, подумав еще немного о вашем предыдущем посте прошлой ночью, я должен согласиться, что, скорее всего, это проблема с моей реализацией WebSocket. Есть ли у вас какие-либо рекомендации относительно хорошей библиотеки WebSocket? Спасибо. - person HartleySan; 23.01.2013
comment
Зависит от того, какую внутреннюю технологию вы хотите использовать — по разным причинам клиентские библиотеки обычно привязаны к конкретной внутренней реализации. У меня есть серверная часть ASP.NET, я использую SignalR и в основном очень доволен этим. Но дополнительные альтернативы смотрите здесь: en.wikipedia.org/wiki/Comparison_of_WebSocket_implementations - person Ken Smith; 23.01.2013