2012-06-26 3 views
1

매우 이상한 문제가 있습니다. 나는 열린 WebSocket을 가지고 있으며, 통신은 완벽하게 작동합니다. 나는 또한 창에 대한 onblur 및 onfocus 이벤트를 가지고 있는데,이 이벤트는 연결을 통해 서버에 알립니다. 그러나이 경우 수신하는 문자열은 null이 아닌 종료 문자입니다. 커뮤니케이션은 그 각각의 흐림/포커스 이벤트에서 보내지는 동일한 문자열을 전송할 때조차도 완벽하게 결점없이 작동합니다. 왜 그런가요? 어떻게 고칠 수 있습니까? 여기 JavaScript WebSocket Null이 아닌 문자열

는 일부 코드입니다 :

$(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'); 
    } 

} 

그리고 여기에 이벤트 화재 때 수신이 아닌 null로 끝나는 문자열의 예 :

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

편집 : 그것은 제안 된의 IT 그 서버 오류 일 수 있으므로 수신 메시지를 디코딩하는 코드는 다음과 같습니다.

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에서만 발생합니다. 같은 WebSocket-protocol을 사용하는 Firefox에서 확인했는데 모든 것이 완벽하게 작동합니다.

+0

서버 오류처럼 보입니다. 서버는 무엇입니까? –

+0

PHP. 그러나 onblur/onfocus 이벤트 외부로 보낼 때는 항상 메시지가 올바르게 표시됩니다. – arik

답변

2

onblur 및 onfocus 이벤트가 여러 번 빠르게 연속적으로 발생하고 있습니다. websocket.send 호출이 빠르게 연속적으로 여러 번 호출된다는 것을 의미합니다.

여러 번의 전송 호출이 서로 가깝게 발생하면 서버에서 한 번의 읽기에서 여러 프레임을 수신 할 확률이 높습니다. 즉, 페이로드의 "가비지"는 실제로 하나 이상의 후속 WebSocket 프레임입니다.

당신은 문제가 수동으로 분리 된 두 개의 같은 자바 스크립트 컨텍스트에서 보내는 일을 복제 할 수 있습니다 충분히 가까이 함께 두 개의 웹 소켓 프레임을 보내드립니다

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

서버가 아마 한 번에 모든 것을 읽을 것 소켓에서.

프레임을 제대로 처리하려면 페이로드 길이 필드를 구문 분석하고 지정된 양의 페이로드 데이터를 읽거나 제거해야합니다. 남은 것은 새로운 프레임의 시작으로 큐에 넣어야합니다.

또한 소켓에서 읽은 하나의 프레임에서 여러 개의 Websocket 프레임을 반환 할 수있을뿐만 아니라 전체 프레임으로 읽을 프레임을 신뢰할 수 없습니다. 하나의 읽기에서 프레임의 절반을 읽고 나머지는 프레임에서 읽을 수 있습니다. 다음 프레임. 즉, 처음 소켓을 읽을 때 3 개의 전체 websocket 프레임과 4 번째 프레임의 1 바이트를 얻은 다음 소켓에서 다음에 읽을 때 4 번째 프레임의 나머지 부분을 얻을 수 있습니다.

일반적으로 다음과 같이 요약 할 수 있습니다. 웹 소켓은 메시지 기반 전송 프로토콜이고 TCP 소켓은 스트리밍 프로토콜입니다. WebSocket은 TCP에 계층화되어 있기 때문에 기본 전송이 메시지 기반이 아니더라도 WebSocket 서버 (및 해당 클라이언트)가 응용 프로그램에 전체 메시지를 제공하기 위해 변환을 수행해야합니다.

+0

당신은 선생님, 절대적으로 맞습니다, 감사합니다! – arik

+0

글쎄, 지금은 코드를 적용, 그러나, 당신이 제안한 테스트를 시도 할 때, 나는 모든 메시지를 올바르게 해독합니까 : 그러나 마지막 메시지가 아닌 일부 횡령 한 문자가 추가됩니다.왜 그런가요? 어떻게 제거 할 수 있습니까? 그들은 분명한 패턴을 공유하지 않기 때문입니다. 예 :'m5§Ë','æ®p'. – arik

+0

편집 : 이러한 중복 문자는 5 개 그룹으로 만 나타납니다 ...? – arik

관련 문제