Make a PHP socket server for WebSocket [handshake]

I am trying to build my own PHP socket server to work with the HTML5 WebSocket API, but I cant follow the handshake step, I read rfc6455 here my PHP server code:

Here is the Javascript code:

var socket = new WebSocket("ws://127.0.0.1:1577/server.php");

socket.onopen = function (e) {
    console.log("openned : "+e.readyState);
}
socket.onclose = function (e) {
    console.log("Socket connection closed : "+e);
}

      

Here's the PHP code:

<?php

set_time_limit(0);
$adr = "127.0.0.1";
$port = 1577;

$m_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$msg = "Welcome...";
$cls = array();

socket_bind($m_sock, $adr, $port);
socket_listen($m_sock, 5);
echo "Server start...\n\n";

do{
        $msgsock = socket_accept($m_sock);

        array_push($cls, $msgsock);
        echo "Connected...\n\n";
        usleep(100);
        //socket_write($msgsock, $msg, strlen($msg)); //this is the 'bug'
        do{
                if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
                   echo "socket_read() fail :" . socket_strerror(socket_last_error($msgsock)) . "\n";
                    break 2;
                }
                if(preg_match("/Sec-WebSocket-Key: (.*)/",$buf,$match)){ 
                        $key =  base64_encode(hash("sha1",trim($match[1])."258EAFA5-E914-47DA-95CA-C5AB0DC85B11")); 
                        $response_header =    "HTTP/1.1 101 Switching Protocols"."\r\n".
                        "Upgrade: websocket"."\r\n".
                        "Connection: Upgrade"."\r\n".
                        "Sec-WebSocket-Accept: $key"."\r\n\r\n";

                        //SERVER RESPONSE ----
                        socket_write($msgsock,$response_header,strlen($response_header));

                        echo "handshake done...";
                };
        } while(1);
        socket_close($msgsock);
} while(1);

      

I always have this error: failed: WebSocket handshake error: invalid status bar Here's the HTTP request:

HTTP request:

Accept-Encoding:gzip, deflate, sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,he;q=0.2
Cache-Control:no-cache
Connection:Upgrade
Cookie:__utma=96992031.134451192.1399804258.1402844967.1402848436.4; __utmz=96992031.1399804258.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _ga=GA1.4.134451192.1399804258; toolbarDisplay=hide
Host:127.0.0.1:1577
Origin:http://127.0.0.1
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:2yODScjZV/dap0DsDSWDFQ==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36

      

Here's the answer generated by the PHP server:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: MDQ1NjFhMzc1YjY5MWQwNTU1ZGIzNDYyZmM0YTc1ODFhMDBlMzdmOQ==

      

+3


source to share


2 answers


You can read the Ratchet source code and see how they did it.



There is a class that implements the handshake here .

+1


source


Just by looking at the answer, it looks like your web trick is wrong, it looks too long. I know this because I had the same problem. If I have the same problem as mine, here's the problem:

SHA-1 returns a hexadecimal value. This value CANNOT be simply converted to base64 as it is. The hexadecimal value must be converted to ascii text first, and then the ascii text value can be base64 encoded.



The simple answer here is to just take the hex value passed in from SHA-1 and split it into 2 character chunks. Take these 2 characters, convert them to normal decimal numbers, and then look at the ascii character code that matches the number.

0


source







All Articles