1

I'm making a simple WebSocket server in PHP. My websocket client connects to it fine, but any time I try to send data through it I get an "Error: INVALID_STATE_ERR: DOM Exception 11" thrown in JavaScript.

This and a couple other questions seem to describe the same problem I'm having but the WebSocket protocol has changed since.

I'm assuming the problem is that my script is handshaking incorrectly as stated in that question. I'm using Chromium 15 which uses WebSocket version 8.

Here's my handshake function (partially my code partially modified from an outdated example I found somewhere):

function dohandshake($user, $buffer)
{
server_log(1, 'Requesting handshake...');

// Determine which version of the WebSocket protocol the client is using
if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/ ", $buffer, $match))
    $version = $match[1];
else 
    return false;

if($version == 8)
{
    // Extract header variables
    if(preg_match("/GET (.*) HTTP/"   ,$buffer,$match)){ $r=$match[1]; }
    if(preg_match("/Host: (.*)\r\n/"  ,$buffer,$match)){ $h=$match[1]; }
    if(preg_match("/Sec-WebSocket-Origin: (.*)\r\n/",$buffer,$match)){ $o=$match[1]; }
    if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$buffer,$match)){ $k = $match[1]; }

    // Generate our Socket-Accept key based on the IETF specifications
    $accept_key = $k . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
    $accept_key = sha1($accept_key, true);
    $accept_key = base64_encode($accept_key);

    $upgrade =  "HTTP/1.1 101 Switching Protocols\r\n" .
                    "Upgrade: websocket\r\n" .
                    "Connection: Upgrade\r\n" .
                    "Sec-WebSocket-Accept: $accept_key";

    socket_write($user->socket, $upgrade, strlen($upgrade));
    $user->handshake = true;
    return true;
}
else 
{
    server_log("Client is trying to use an unsupported WebSocket protocol ({$version})");
    return false;
}
}

I tested the key generation code on several examples I found and it seems to have returned the correct key according to those examples

Community
  • 1
  • 1
DWilliams
  • 451
  • 8
  • 22

1 Answers1

5

Dumb solution of the century, apparently two "\r\n" newlines are expected at the end of the handshake response.

DWilliams
  • 451
  • 8
  • 22
  • 3
    FYI: TCP protocols often use `\r\n` (carriage return + line feed) to indicate a new line. `\r\n\r\n` is used by HTTP to indicate the end of the handshake. The WebSocket handshake is designed to be HTTP compatible. – kanaka Nov 17 '11 at 14:33