Lo stesso problema!!!
Sto cercando di scrivere una piccola applicazione in cui il client rimane in attesa di un evento da parte del server.
Sulla parte client utilizzo una WebSocket e sulla parte server utilizzo la socket tramite PHP.
Nella risposta effettuo l'handshake per la webSocket ma c'è qualcosa che non va!


Codice lato client
codice:
function startConnection(){
    var message = 'Ciao';
    var port = 2518;


    // creazione websocket
    var websocket = new WebSocket("ws://localhost:"+ port +"/LipariStudios/tesiLaurea/sketchApps/22/server.php");


    websocket.onopen = function(evt) {
        console.log(evt);


        websocket.send(message);
        websocket.close();
    };
    websocket.onclose = function(evt) { console.log(evt); };
    websocket.onmessage = function(evt) { console.log(evt); };
    websocket.onerror = function(evt) { console.log(evt); };
};

Sul lato server
codice:
// conf
//$host = 'localhost';
//$host = 'liparistudios.hostinggratis.it';
$host = '127.0.0.1';
//$host = '192.168.1.171';
$local = 'LipariStudios/tesiLaurea/sketchApps/22/server.php';   //  local
//$local = 'App/socketTest/01/server.php';   // remote
$data = 'risposta dalla socket';
$port = 2518;


$maxBufferSize = 2048;
$key = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';


$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)    or die("Failed: socket_create()");
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)   or die("Failed: socket_option()");
//socket_bind($socket, $host.'/'.$local, $port)             or die("Failed: socket_bind()\n");
socket_bind($socket, $host, $port)             or die("Failed: socket_bind()\n");


// attesa
socket_listen($socket,20)                                 or die("Failed: socket_listen()");


socket_accept($socket);


// connessione in entrata
while(true){
    $numBytes = @socket_recv($socket, $buffer, $maxBufferSize, MSG_WAITALL);
    if ($numBytes === false) {
        $sockErrNo = socket_last_error($socket);
        switch ($sockErrNo)
        {
            case 102: // ENETRESET    -- Network dropped connection because of reset
            case 103: // ECONNABORTED -- Software caused connection abort
            case 104: // ECONNRESET   -- Connection reset by peer
            case 108: // ESHUTDOWN    -- Cannot send after transport endpoint shutdown -- probably more of an error on our part, if we're trying to write after the socket is closed.  Probably not a critical error, though.
            case 110: // ETIMEDOUT    -- Connection timed out
            case 111: // ECONNREFUSED -- Connection refused -- We shouldn't see this one, since we're listening... Still not a critical error.
            case 112: // EHOSTDOWN    -- Host is down -- Again, we shouldn't see this, and again, not critical because it's just one connection and we still want to listen to/for others.
            case 113: // EHOSTUNREACH -- No route to host
            case 121: // EREMOTEIO    -- Rempte I/O error -- Their hard drive just blew up.
            case 125: // ECANCELED    -- Operation canceled


                echo "Unusual disconnect on socket " . $socket;
                // disconnect
                break;
            default:
                echo 'Errore sconosciuto ['. $sockErrNo .']: ' . socket_strerror($sockErrNo);
        }


    }
    elseif ($numBytes == 0) {
        // disconnect
        echo "Client disconnected. TCP connection lost: " . $socket;
    }
    else {
            $tmp = str_replace("\r", '', $buffer);
            if (strpos($tmp, "\n\n") === false ) {
                continue; // If the client has not finished sending the header, then wait before sending our upgrade response.
            }


            // handshake ////////////////////////////////


            // • prendi gli headers e lo componi come un array associativo e lo prendi dul buffer
            $headers = array();
            $lines = explode("\n",$buffer);
            foreach ($lines as $line) {
                if (strpos($line,":") !== false) {
                    $header = explode(":",$line,2);
                    $headers[strtolower(trim($header[0]))] = trim($header[1]);
                }
                elseif (stripos($line,"get ") !== false) {
                    preg_match("/GET (.*) HTTP/i", $buffer, $reqResource);
                    $headers['get'] = trim($reqResource[1]);
                }
            }


            // • prendi il protocolo   //  solitamente chat
            $subProtocol = (isset($headers['sec-websocket-protocol'])) ? $headers['sec-websocket-protocol'] : "";


            // • prendi il sub protocollo  //  solitamente super chat
            $extensions = (isset($headers['sec-websocket-extensions'])) ? $headers['sec-websocket-extensions'] : "";


            // • valore chiave 258EAFA5-E914-47DA-95CA-C5AB0DC85B11


            // • fai lo SHA-1 della key insieme alla chiave
            $webSocketKeyHash = sha1($headers['sec-websocket-key'] . $key);


            // • chr corrispondente ascii di un carattere
            // • hexdec da una stringa esadecimale ne ritorna il valore decimale


            $rawToken = "";
            for ($i = 0; $i < 20; $i++) {
              $rawToken .= chr(hexdec(substr($webSocketKeyHash,$i*2, 2)));
            }
            $handshakeToken = base64_encode($rawToken) . "\r\n";


            // • componi la chiave
//            Sec-WebSocket-Accept: $handshakeToken . $subProtocol . $extensions\r\n


            // • componi la risposta
            $handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: $handshakeToken$subProtocol$extensions\r\n";


            // oppure
//            $handshakeResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: $handshakeToken$subProtocol$extensions\r\nSec-WebSocket-Protocol: chat";


            // • invia la risposta alla socket
            socket_write($socket,$handshakeResponse,strlen($handshakeResponse));


    }
}




socket_close($socket);

Da queste immagini si vede lo strano comportamento!