2012-06-26 54 views
1

我有一个很奇怪的问题。我有一个开放的WebSocket,沟通工作完美。我也有窗口的onblur和onfocus事件,通过所述连接通知服务器。但是,在这种情况下,我收到的字符串是非空终止的。除此之外,即使在发送相应的模糊/焦点事件发送的字符串时,通信的工作也是完全无懈可击的。为什么是这样,它如何解决?JavaScript WebSocket非空终止的字符串

下面是一些代码:

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

} 

编辑:它只发生在铬。我在Firefox上检查了它,它使用相同的WebSocket协议,并且在那里一切正常。

+0

看起来像服务器错误。什么是服务器? –

+0

PHP。但是,当我将它发送到onblur/onfocus事件之外时,这条消息始终是正确的。 – arik

回答

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套接字是流协议。由于WebSocket在TCP上分层,这意味着即使底层传输不是基于消息的,WebSocket服务器(和客户端)也必须进行翻译才能将整个消息呈现给应用程序。

+0

您先生,绝对正确,谢谢! – arik

+0

好吧,我现在修改了代码,但是,在尝试你建议的测试时,我确实解码了所有的消息,但是,有一些乱码字符被添加到非最后的消息中。为什么是这样,我该如何删除/检测它们?因为他们没有分享任何可辨别的模式。例如:'m5'Ë','æ'p'。 – arik

+0

编辑:我注意到这些多余的字符只能在五个组中进行...? – arik