Dayzza
Dayzza

Reputation: 1557

How can Javascript client connect to PHp socket Server?

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.

Upvotes: 9

Views: 12773

Answers (5)

Nabi K.A.Z.
Nabi K.A.Z.

Reputation: 10724

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

Upvotes: 10

Tudor Constantin
Tudor Constantin

Reputation: 26861

Shortly saying - you can't do that - it would be a security breach to let client side code open socket connections.

However, you could simulate that - send your data to another PHP page as an AJAX request, then make that PHP page communicate through the socket.

Update 2017:

In the mean time, websockets became a thing. Please note that the websocket protocol is a different thing than generic networking sockets

Upvotes: -2

Mark Phillips
Mark Phillips

Reputation: 1541

Answering an old question in case people find it as I did via Google.

Nowadays nearly all contemporary browsers support the WebSocket Javascript API. Via WS it's possible for client JS in the browser to open full duplex sockets to severs written in PHP or other languages. The server must implement the WS protocol, but there are WS libraries now for PHP, Java, and other languages.

At this moment of writing, WS implementations still seem like a bit of a moving target, but, I'm currently working with WS/JS browser clients communicating with a WS/Java server and it does seem to be working.

Suggest Googling for WS implementations in your server language of choice.

Hope this helps!

Upvotes: 7

Eric Hodonsky
Eric Hodonsky

Reputation: 5897

Try this:

http://code.google.com/p/phpwebsocket/

Upvotes: -1

Quentin
Quentin

Reputation: 943686

I'm not aware of anything that provides arbitrary socket capabilities for JS. There is limited support for Web Sockets (which I think will require you to modify the server to conform to the space). Failing that, simple XHR might meet your needs (which would require that you modify the server to act as a web service). If the service runs on a different origin to the page, then you will need to use CORS or use a work around such as JSONP.

Upvotes: 0

Related Questions