Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP stream socket not working with HTML5 socket?

It seems that most HTML5 web socket example online with PHP are using the socket plugin. Is it possible to use stream_socket_server with HTML5 web socket?

If yes, I am trying to build a simple socket server + client with PHP stream_socket_server function. Here is the code:

PHP socket server:

<?php   
$server = stream_socket_server("tcp://localhost:8080", $errno, $errorMessage);

if ($server === false) {
    throw new UnexpectedValueException("Could not bind to socket: $errorMessage");
}

for (;;) {
    $client = stream_socket_accept($server);

    if ($client) {
        echo 'Connection accepted from '.stream_socket_get_name($client, false) . "\n";
        stream_copy_to_stream($client, $client);
    }
}

HTML5 Web Socket Client.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Client Testing</title>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
</head>
<body>
    <button id="send">Testing button</button>
    <script>
        websocket = new WebSocket("ws://localhost:8080");
        websocket.onopen = function(evt) { /* do stuff */ }; //on open event
        websocket.onclose = function(evt) { /* do stuff */ }; //on close event
        websocket.onmessage = function(evt) { /* do stuff */ }; //on message event
        websocket.onerror = function(evt) { /* do stuff */ }; //on error event
        $('#send').click( function(){
            websocket.send("This is a testing message"); //send method
        });
        //websocket.close(); //close method
    </script>
</body>
</html>

And this is the return when I am connecting:

WebSocket connection to 'ws://localhost:8080/' failed: Error during WebSocket handshake: net::ERR_INVALID_HTTP_RESPONSE

What have I missed? How do I return a valid HTTP response?

like image 311
cytsunny Avatar asked Oct 29 '22 09:10

cytsunny


1 Answers

You get this error ERR_INVALID_HTTP_RESPONSE because you don't send the appripriate response through your socket.

A response from the server to the client looks like this:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

So you need to write that to the socket:

socket_write($accept, $httpResponse);

You also need to implement polling via socket_select(), currently your program is not able to handle more than a single connection.

Also don't forget to use socket_close() when you're done.


Old Answer

A generic socket is opened upon OSI layer 4. You open a UNIX socket, a TCP socket, a UDP socket.

It is also possible to open sockets on lower OSI layers like for ICMP or even IP which are generally called "raw sockets".

A Websocket is an Application layer protocol - OSI layer 7. A Websocket uses a generic socket (single duplex TCP connection) to send and receive its data.

You cannot connect one to the other without further implementation. A Websocket is build upon a normal socket.

See:

  • https://en.wikipedia.org/wiki/OSI_model
  • https://en.wikipedia.org/wiki/WebSocket
like image 56
Daniel W. Avatar answered Nov 15 '22 04:11

Daniel W.