Reputation: 4956
I am developing a simple websocket server in PHP. I know there are quite a few existing implementations but I want to make my own so to learn the protocol better. I managed to do the handshaking fine and my clients connect to the server. I also managed to decode the data from the client but I have problems sending back messages. The client disconnects when it receives my response. Firefox says The connection to ws://localhost:12345/ was interrupted while the page was loading.
.
I used this answer as a guide.
Here is my code for wrapping the data:
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: I tried it with Chrome and I got the following error, printed in the console: A server must not mask any frames that it sends to the client.
I put some console printouts on the server. It is a basic echo server. I try with aaaa
. So the actual wrapped message must be 6 bytes. Right?
Chrome prints the above error. Note also that after wrapping the message I simply write it to the socket:
$sent = socket_write($client, $bytesFormatted, strlen($bytesFormatted));
$this->say("! " . $sent);
It prints 6 meaning 6 bytes are actually written to the wire.
If I try with aaa
, Chrome doesn't print the error but doesn't call my onmessage handler either. It hangs as if waiting for more data.
Any help highly appreciated. Thanks.
Upvotes: 16
Views: 2773
Reputation: 196
I had the same problem: for some messages sent from the server there was no response in the browser, for some the error "A server must not mask any frames ..." was displayed, though I did not add any mask. The reason was in the handshake sent. The handshake was:
"HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
...
"WebSocket-Location: ws://{$host}{$resource}\r\n\r\n" . chr(0)
That chr(0) was the reason, after I removed it everything works.
Upvotes: 4
Reputation: 46
When I wrote my websocket classes, I had the same issue. In my case, I used output buffering to determine that I was echo'ing something out before I sent the reply. Might try that and see if it's the problem.
Upvotes: 0