2012-10-29 2 views
15

PHP에서 간단한 websocket 서버를 개발 중입니다. 몇 가지 기존 구현이 있다는 것을 알고 있지만 더 나은 프로토콜을 배우기 위해 자체적으로 만들고 싶습니다. 나는 핸드 쉐이킹을 잘 할 수 있었고 클라이언트는 서버에 연결했다. 또한 클라이언트의 데이터를 디코딩 할 수 있었지만 메시지를 다시 보내는 데 문제가 있습니다. 클라이언트는 내 응답을 수신하면 연결을 끊습니다. Firefox는 The connection to ws://localhost:12345/ was interrupted while the page was loading.라고 말합니다.PHP의 간단한 websocket 서버

this answer을 가이드로 사용했습니다. 여기

는 데이터를 포장 내 코드입니다 :

private function wrap($msg = ""){ 
    $length = strlen($msg); 
    $this->log("wrapping (" . $length . " bytes): " . $msg); 

    $bytesFormatted = chr(129); 
    if($length <= 125){ 
     $bytesFormatted .= chr($length); 
    } else if($length >= 126 && $length <= 65535) { 
     $bytesFormatted .= chr(126); 
     $bytesFormatted .= chr(($length >> 8) & 255); 
     $bytesFormatted .= chr(($length  ) & 255); 
    } else { 
     $bytesFormatted .= chr(127); 
     $bytesFormatted .= chr(($length >> 56) & 255); 
     $bytesFormatted .= chr(($length >> 48) & 255); 
     $bytesFormatted .= chr(($length >> 40) & 255); 
     $bytesFormatted .= chr(($length >> 32) & 255); 
     $bytesFormatted .= chr(($length >> 24) & 255); 
     $bytesFormatted .= chr(($length >> 16) & 255); 
     $bytesFormatted .= chr(($length >> 8) & 255); 
     $bytesFormatted .= chr(($length  ) & 255); 
    } 

    $bytesFormatted .= $msg; 
    $this->log("wrapped (" . strlen($bytesFormatted) . " bytes): " . $bytesFormatted); 
    return $bytesFormatted; 
} 

UPDATE : 나는 크롬 그것을 시도하고 나는 콘솔에 인쇄 다음과 같은 오류 얻었다 : A server must not mask any frames that it sends to the client.

좀 콘솔을 넣어 서버의 인쇄물. 기본 에코 서버입니다. 나는 aaaa으로 시도합니다. 따라서 실제 포장 된 메시지는 6 바이트 여야합니다. 권리?

enter image description here

크롬은 위의 오류를 인쇄합니다. 참고 또한 메시지를 포장 한 후 나는 단순히 소켓에 기록 :

$sent = socket_write($client, $bytesFormatted, strlen($bytesFormatted)); 
$this->say("! " . $sent); 

이 6 바이트가 실제로 와이어에 기록됩니다 6 의미를 인쇄합니다.

aaa으로 시도하면 Chrome에서 오류를 인쇄하지 않지만 내 onmessage 처리기를 호출하지 않습니다. 더 많은 데이터를 기다리는 것처럼 응답하지 않습니다.

도움이 되었습니까? 감사.

+0

wireshark를 사용하여 와이어를 통해 전송되는 바이트가 여기 코드에서 생성 된 것과 일치하는지 확인 했습니까? 그리고 다른 어떤 코드도 메시지의 시작으로 해석 될 수있는 추가 데이터를 보내지 않습니다. – simonc

+0

@imonc wireshark가 패키지를 볼 수 없기 때문에 같은 컴퓨터에 있습니다. 나는 그것을 어떻게 든 저지하려고 노력할 것이다. 감사. –

+0

임시로 Firefox를 실행할 수있는 두 번째 시스템이 있습니까? – simonc

답변

3

같은 문제가 있습니다. 서버에서 보낸 일부 메시지의 경우 브라우저에 아무런 응답이 없었습니다. 일부 오류에 대해 "서버에서 모든 프레임을 마스크하면 안됩니다 ..."라는 메시지가 표시되었지만 아무 것도 추가하지 않았습니다. 마스크. 핸드 셰이크가 전송 된 이유가 있습니다. 악수했다 : 나는 그것을 제거 후

"HTTP/1.1 101 Web Socket Protocol Handshake\r\n" . 
... 
"WebSocket-Location: ws://{$host}{$resource}\r\n\r\n" . chr(0) 

CHR (0) 이유는 것을, 모든 작동합니다.

+0

당신은 천재입니다. 고맙습니다. –

1

websocket 클래스를 작성했을 때 같은 문제가있었습니다. 필자는 출력 버퍼링을 사용하여 회신을 보내기 전에 무언가를에 출력했는지 확인했습니다. 시도해보고 문제인지 확인해보십시오.