How can Javascript client connect to PHp socket Server?

Viewed 11644

Hi I have a running socket server written with PHP.

The server is listening for connections.. any idea how my client(written in javascript) is going to connect to the server and send data to it?

PS: I only know how to connect a php client to the socket server but unsure how to connect a javascript client.

Thanks all for your time.

5 Answers

I use standard WebSocket API for client. And core PHP socket for server side.

know, send and received data use a header on the browser with websocket. But the code PHP socket, send and received without header and just send plain data.

So we need to simulate header on the socketing server side.

For learning and know how do it, I write this clear sample code, With this code you can send a phrase to server and receive reverse phrase that in client.

server.php

<?php
//Code by: Nabi KAZ <www.nabi.ir>

// set some variables
$host = "127.0.0.1";
$port = 5353;

// don't timeout!
set_time_limit(0);

// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0)or die("Could not create socket\n");

// bind socket to port
$result = socket_bind($socket, $host, $port)or die("Could not bind to socket\n");

// start listening for connections
$result = socket_listen($socket, 20)or die("Could not set up socket listener\n");

$flag_handshake = false;
$client = null;
do {
    if (!$client) {
        // accept incoming connections
        // client another socket to handle communication
        $client = socket_accept($socket)or die("Could not accept incoming connection\n");
    }

    $bytes =  @socket_recv($client, $data, 2048, 0);
    if ($flag_handshake == false) {
        if ((int)$bytes == 0)
            continue;
        //print("Handshaking headers from client: ".$data."\n");
        if (handshake($client, $data, $socket)) {
            $flag_handshake = true;
        }
    }
    elseif($flag_handshake == true) {
        if ($data != "") {
            $decoded_data = unmask($data);
            print("< ".$decoded_data."\n");
            $response = strrev($decoded_data);
            socket_write($client, encode($response));
            print("> ".$response."\n");
            socket_close($client);
            $client = null;
            $flag_handshake = false;
        }
    }
} while (true);

// close sockets
socket_close($client);
socket_close($socket);

function handshake($client, $headers, $socket) {

    if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match))
        $version = $match[1];
    else {
        print("The client doesn't support WebSocket");
        return false;
    }

    if ($version == 13) {
        // Extract header variables
        if (preg_match("/GET (.*) HTTP/", $headers, $match))
            $root = $match[1];
        if (preg_match("/Host: (.*)\r\n/", $headers, $match))
            $host = $match[1];
        if (preg_match("/Origin: (.*)\r\n/", $headers, $match))
            $origin = $match[1];
        if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match))
            $key = $match[1];

        $acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
        $acceptKey = base64_encode(sha1($acceptKey, true));

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

        socket_write($client, $upgrade);
        return true;
    } else {
        print("WebSocket version 13 required (the client supports version {$version})");
        return false;
    }
}

function unmask($payload) {
    $length = ord($payload[1]) & 127;

    if ($length == 126) {
        $masks = substr($payload, 4, 4);
        $data = substr($payload, 8);
    }
    elseif($length == 127) {
        $masks = substr($payload, 10, 4);
        $data = substr($payload, 14);
    }
    else {
        $masks = substr($payload, 2, 4);
        $data = substr($payload, 6);
    }

    $text = '';
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i % 4];
    }
    return $text;
}

function encode($text) {
    // 0x1 text frame (FIN + opcode)
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);

    if ($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)$header = pack('CCS', $b1, 126, $length);
    elseif($length >= 65536)
    $header = pack('CCN', $b1, 127, $length);

    return $header.$text;
}

client.htm

<html>
<script>
//Code by: Nabi KAZ <www.nabi.ir>

var socket = new WebSocket('ws://localhost:5353');

// Open the socket
socket.onopen = function(event) {
    var msg = 'I am the client.';

    console.log('> ' + msg);

    // Send an initial message
    socket.send(msg);

    // Listen for messages
    socket.onmessage = function(event) {
        console.log('< ' + event.data);
    };

    // Listen for socket closes
    socket.onclose = function(event) {
        console.log('Client notified socket has closed', event);
    };

    // To close the socket....
    //socket.close()

};
</script>
<body>
<p>Please check the console log of your browser.</p>
</body>
</html>

Manual: first run php server.php on CLI and then open http://localhost/client.htm on browser.

You can see result:

http://localhost/client.htm
> I am the client.
< .tneilc eht ma I

php server.php
< I am the client.
> .tneilc eht ma I

Be careful it's just a sample code for test send and receive data, And it is not useful for executive work.

I suggest you use these projects:

https://github.com/ghedipunk/PHP-Websockets
https://github.com/esromneb/phpwebsocket
https://github.com/acbrandao/PHP/tree/master/ws
https://github.com/srchea/PHP-Push-WebSocket/
http://socketo.me/

And also I suggest you these articles for more details:

http://www.abrandao.com/2013/06/websockets-html5-php/
http://cuelogic.com/blog/php-and-html5-websocket-server-and-client-communication/
http://srchea.com/build-a-real-time-application-using-html5-websockets

Related