Pages

PHP: PHP WebSocket Program and Running It on Ubuntu

 

Writing a WebSocket PHP Program and Running It on Ubuntu

WebSockets allow real-time communication between a client and a server. Below is a simple example of a PHP WebSocket server and instructions to run it on an Ubuntu machine.


PHP WebSocket Server

Create a file named websocket-server.php and copy the following code:

<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();

$address = '127.0.0.1'; // Localhost address
$port = 8080;           // Port number

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);

if (!socket_bind($sock, $address, $port)) {
    die("Could not bind to socket: " . socket_strerror(socket_last_error()) . PHP_EOL);
}

socket_listen($sock);

echo "WebSocket Server started on ws://$address:$port\n";

$clients = [];

while (true) {
    $changed = $clients;
    $changed[] = $sock;

    // Check for activity on sockets
    socket_select($changed, $write, $except, 0, 10);

    if (in_array($sock, $changed)) {
        $newClient = socket_accept($sock);
        $clients[] = $newClient;

        // Perform WebSocket handshake
        $header = socket_read($newClient, 1024);
        performHandshake($header, $newClient, $address, $port);
        
        echo "New client connected\n";
        unset($changed[array_search($sock, $changed)]);
    }

    foreach ($changed as $client) {
        $data = socket_read($client, 1024, PHP_BINARY_READ);
        
        if ($data === false) {
            // Client disconnected
            socket_close($client);
            unset($clients[array_search($client, $clients)]);
            echo "Client disconnected\n";
            continue;
        }

        // Handle received data
        $decodedData = decode($data);
        echo "Received message: $decodedData\n";

        // Send response
        $response = encode("Server received: $decodedData");
        socket_write($client, $response);
    }
}

// Functions
function performHandshake($header, $clientSocket, $host, $port)
{
    $lines = preg_split("/\r\n/", $header);
    $key = '';

    foreach ($lines as $line) {
        if (preg_match('/^Sec-WebSocket-Key: (.*)/', $line, $matches)) {
            $key = $matches[1];
        }
    }

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

    $headers = "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($clientSocket, $headers);
}

function encode($payload)
{
    $length = strlen($payload);

    if ($length <= 125) {
        return chr(129) . chr($length) . $payload;
    } else {
        return '';
    }
}

function decode($data)
{
    $payloadLength = ord($data[1]) & 127;

    if ($payloadLength <= 125) {
        return substr($data, 2);
    } else {
        return '';
    }
}

How to Run the Server

  1. Install PHP Sockets Extension: Open a terminal and run the following command to ensure the PHP sockets extension is installed:

    sudo apt update
    sudo apt install php-cli php-sockets
    
  2. Run the WebSocket Server: Navigate to the directory where you saved websocket-server.php and start the server:

    php websocket-server.php
    

    You should see the message:

    WebSocket Server started on ws://127.0.0.1:8080
    
  3. Test the Server: Use a WebSocket client like:

    • WebSocket King Client (online tool)
    • Browser Console:
      let ws = new WebSocket('ws://127.0.0.1:8080');
      ws.onopen = () => console.log('Connected');
      ws.onmessage = (event) => console.log('Message:', event.data);
      ws.send('Hello Server');
      
    • Custom WebSocket client in Node.js or Python.

Stopping the Server

To stop the server, press Ctrl+C in the terminal.

Let me know if you need further assistance!