JavaScript WebSocket非空终止字符串

时间:2012-06-26 08:51:11

标签: javascript string websocket null-terminated

我有一个非常奇怪的问题。我有一个开放的WebSocket,通信工作完美。我还有窗口的onblur和onfocus事件,它通过所述连接通知服务器。但是,在这种情况下,我收到的字符串是非空终止的。即使发送在相应模糊/焦点事件上发送的相同字符串,通信也绝对无可挑剔。为什么会这样,以及如何解决?

以下是一些代码:

$(document).ready(function(){

    initializeEverything();

    window.onblur = function(){ notifyFocusChange(false); };

    window.onfocus = function(){ notifyFocusChange(true); };

});

function notifyFocusChange(present){

    if(present){
        webSocket.send('presence:present');
    }else{
        webSocket.send('presence:absent');
    }

}

以下是我在事件触发时收到的非空终止字符串的示例:

presence:absentÏ┘ê÷/à°äJ÷ÝÿLÓ▓ùM÷Ýÿ[

编辑:有人建议它可能是服务器错误,所以这里是解码传入消息的代码:

private function decode($payload) {

    $length = ord($payload[1]) & 127;

    if ($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    } elseif ($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    } else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }

    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }

    return $text;

}

编辑:它只发生在Chrome中。我在Firefox上检查过它,它使用相同的WebSocket协议,一切都很好。

1 个答案:

答案 0 :(得分:2)

onblur和onfocus事件可能会连续多次发生。这意味着websocket.send调用也会被快速连续多次快速调用。

如果多个发送呼叫足够接近,那么很有可能您在服务器的单次读取中会收到多个帧,我相信这就是您所看到的。换句话说,有效负载中的“垃圾”实际上是一个或多个后续WebSocket帧。

您可以手动复制问题,在同一个Javascript环境中执行两个单独的发送:

function do_test () {
    ws.send("data1");
    ws.send("data2");
}

这将发送两个足够靠近的WebSocket框架,服务器可能会从套接字中一次读取它们。

为了正确处理帧,您必须解析有效负载长度字段,并且只读取/取消屏蔽指定数量的有效负载数据。剩下的任何东西都需要排队作为新框架的开头。

此外,不仅可以从套接字的一次读取中返回多个Websocket帧,而且不能依赖于作为整个帧读取的帧:您可以在一次读取中读取一半帧而在下一次读取中读取另一半帧。帧。换句话说,第一次从套接字读取时,您可能会获得3个完整的websocket框架加上第4帧的1个字节,然后在下一个从套接字读取时,您将获得第4帧的其余部分。

这通常可以这样概括:WebSockets是基于消息的传输协议,而TCP套接字是流协议。由于WebSockets是在TCP上分层的,这意味着WebSocket服务器(以及客户端)必须进行转换以将整个消息呈现给应用程序,即使底层传输不是基于消息的。