2

ChromeのWebRTCAPIと、W3Cの仕様およびSOに関するその他の質問に従って自分で作成したWebSocketスクリプトを使用して、基本的なビデオチャットアプリをセットアップしました。

ただし、一方のPCがWebSocket接続を介してもう一方のPCにICE候補情報を送信すると、JSON文字列化された候補情報の最後に文字化けしたテキストの束が添付されることがあります。ただし、この問題はたまにしか発生せず、createOfferメソッドとcreateAnswerメソッドを介して送信されたSDP情報では発生しません。

私が話していることの例については、次のリンクを参照してください: http ://s1290.beta.photobucket.com/user/HartleySan83/media/NGdata_zps0a7203e7.png.html?sort=3&o=0

JSON文字列化された候補情報は常に「}}」で終わるため、WebSocketサーバースクリプトにif条件を追加することで、この問題を回避し、ビデオチャットアプリを機能させることができました。残念ながら、これは避けたいハックです。さらに、そもそもなぜこれが起こっているのか知りたいのです。

候補者情報を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));

  }

}

インターネットで同じ問題を抱えている人を探しましたが、スペックにこれについて話している人や何かが見つからないので、コードに問題があると思います。

問題の原因について誰もが提供できるガイダンスをいただければ幸いです。ありがとうございました。

4

2 に答える 2

3

さて、ようやく問題が見つかりました。私のサーバー側のWebSocketコードは確かに間違っていました。問題は、私が長さを誤って計算していたことでした。残念ながら、私はPHPのWebSocketについて見つけたページに依存していましたが、そのページのコードに多くのエラーがあり、徐々に気づき始めました。とにかく、クライアントからサーバーに送信されるメッセージの長さを計算する適切な方法は次のとおりです。

$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ビデオはうまく機能しています。

于 2013-01-23T13:46:31.847 に答える
0

文字化けしたバイナリデータは、クライアント1がWebsocketサーバーに送信する前に追加されていますか?または、WebSocketサーバーによって処理された後にのみclient2に表示されますか?シグナリングサーバー(この場合はSignalR)に、PeerConnections間で送信していたSDPを破損するバグがあったという同様の問題が発生したため、質問します。

于 2013-01-22T04:40:38.353 に答える