2012-06-26 160 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