我使用Chrome中的WebRTC API以及我按照W3C规范和此处的其他问题编写的WebSocket脚本,设置了基本的视频聊天应用程序。

但是,有时候,当一台PC通过WebSocket连接将ICE候选信息发送到另一台PC时,一堆乱码文本会附加到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));

  }

}


我在Internet上搜索高低寻找相同问题的其他人,但是在规范中我找不到任何人谈论此事,因此我想我的代码有问题。

任何人都可以提供有关问题根源的任何指导,将不胜感激。
谢谢。

最佳答案

好吧,我终于找到了问题。我的服务器端WebSocket代码确实错误。问题是我计算长度不正确。不幸的是,我依靠的是我在PHP中找到的有关WebSockets的页面,事实证明,该页面的代码中存在许多错误,我逐渐开始意识到这一点。无论如何,这是计算从客户端发送到服务器的消息长度的正确方法:

$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视频效果很好。

09-20 22:49