4

I try to make my own PHP socket Server in order to work with HTML5 WebSocket API, but i can not do the handshake step, i read the [rfc6455][1] here my PHP Server code :

Here 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 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: Error during WebSocket handshake: Invalid status line [1]: https://www.rfc-editor.org/rfc/rfc6455

Here the HTTP request :

the 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 the reponse generated by the PHP server :

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: MDQ1NjFhMzc1YjY5MWQwNTU1ZGIzNDYyZmM0YTc1ODFhMDBlMzdmOQ==
3
  • It may be worth if you paste what request you get and what response you are sending Commented Nov 19, 2014 at 23:05
  • i add the Javascript code (request) and the response already in the php code here => socket_write($msgsock,$response_header,strlen($response_header)); Commented Nov 19, 2014 at 23:10
  • No, I mean the actual HTTP request and the HTTP response generated by your code. Commented Nov 19, 2014 at 23:24

3 Answers 3

1

You can read the source-code of Ratchet and see how they've done.

There is a class which implements the handshake here.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you to both i finnaly found the bug is the socket_write before the second loop i corrected the code :)
0

Just by looking at the response it appears like your websocket accept looks wrong, it looks like it's too long. I know this because I had the exact same problem. If it's the same problem I had, here's the issue:

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

The simple answer here is to simply take the hex value passed back from SHA-1 and break it into chunks of 2 characters. Take those 2 characters, convert them to normal decicmal numbers and then do a look-up to what ascii character code the number corresponds too.

1 Comment

tanks to your answer but i finally found the solution if you're intrested here : github.com/mikadev/websocket-server-php the entire code :)
0

Just add a third parameter 'true' in your hash function call. so it will looks like this :

hash("sha1",trim($match[1])."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true)

For more informations PHP Hash Function

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.