Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions examples/php8-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# PHP 8 WebSocket Example (Ratchet)

This example provides a minimal WebSocket **server** and **client** compatible with **PHP 8.3+** (including PHP 8.4), demonstrating a modern and fully working setup with Ratchet.

It showcases:

* A simple Ratchet WebSocket server (tested with Ratchet >= 0.4)
* A standalone PHP client using the **`ratchet/pawl`** library
* Full compatibility with Linux and macOS

> **Note**
> The client uses `ratchet/pawl`, which is **not a dependency of Ratchet itself**.
> We keep it separate to avoid introducing new PHP version requirements into Ratchet’s core `composer.json`.

---

## Requirements

* PHP `>=7.4` (required by `ratchet/pawl`)
* Ratchet (already installed in the main project)

---

## How to run

### 1. Install Ratchet dependencies (from the project root)

```bash
composer install
```

### 2. Move into the `php8-demo` folder

```bash
cd examples/php8-demo
```

### 2. Install the client dependency (inside the `php8-demo` folder)

```bash
composer install
```

**Note:**
This creates a dedicated `composer.lock` and `vendor` folder inside the example folder, keeping the demo self-contained and avoiding new dependencies in Ratchet itself.

### 3. Start the WebSocket server

```bash
php server.php
```

You should see:

```
WebSocket server started at ws://127.0.0.1:8080
```

### 4. Run the PHP client

```bash
php client.php
```

Expected output:

```
Connected to WebSocket server
Message sent: Hello from PHP 8 client!
Message received from server: Client <number> says: Hello from PHP 8 client!
Connection closed
```

---

## Tested with

| OS | PHP Version |
| ----- | ----------- |
| Linux | 8.3.x |
| macOS | 8.4.x |

This example ensures full compatibility with modern PHP versions without affecting Ratchet’s backward compatibility.
41 changes: 41 additions & 0 deletions examples/php8-demo/client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

require __DIR__ . '/vendor/autoload.php';

use Ratchet\Client\Connector;
use React\EventLoop\Loop;

$loop = Loop::get();

$connector = new Connector($loop);

$connector('ws://127.0.0.1:8080')
->then(function(Ratchet\Client\WebSocket $conn) use ($loop) {

echo "[" . date('H:i:s') . "] Connected to WebSocket server\n";

// Send a test message
$message = "Hello from PHP 8 client!";
$conn->send($message);
echo "[" . date('H:i:s') . "] Message sent: {$message}\n";

// When a message arrives
$conn->on('message', function($msg) use ($conn, $loop) {
echo "[" . date('H:i:s') . "] Received from server: {$msg}\n";

// Close connection after receiving a message
$conn->close();
$loop->stop();
});

// When the connection closes
$conn->on('close', function() {
echo "[" . date('H:i:s') . "] Connection closed\n";
});

}, function(\Exception $e) use ($loop) {
echo "[" . date('H:i:s') . "] Could not connect: {$e->getMessage()}\n";
$loop->stop();
});

$loop->run();
6 changes: 6 additions & 0 deletions examples/php8-demo/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"require": {
"ratchet/pawl": "^0.4",
"react/event-loop": "^1.3"
}
}
51 changes: 51 additions & 0 deletions examples/php8-demo/server.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

require __DIR__ . '/../../vendor/autoload.php';

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\Http\HttpServer;

class DemoChat implements MessageComponentInterface {
protected array $clients = [];

public function onOpen(ConnectionInterface $conn) {
$this->clients[$conn->resourceId] = $conn;
echo "[" . date('H:i:s') . "] New connection: ({$conn->resourceId})\n";
}

public function onMessage(ConnectionInterface $from, $msg) {
echo "[" . date('H:i:s') . "] Message received from {$from->resourceId}: $msg\n";

foreach ($this->clients as $client) {
try {
$client->send("Client {$from->resourceId} says: $msg");
} catch (\Exception $e) {
echo "[" . date('H:i:s') . "] Error while sending message to client {$client->resourceId}: {$e->getMessage()}\n";
}
}
}

public function onClose(ConnectionInterface $conn) {
unset($this->clients[$conn->resourceId]);
echo "[" . date('H:i:s') . "] Connection closed: ({$conn->resourceId})\n";
}

public function onError(ConnectionInterface $conn, \Exception $e) {
echo "[" . date('H:i:s') . "] Error: {$e->getMessage()}\n";
$conn->close();
}
}

// Running WebSocket server at ws://127.0.0.1:8080
$server = IoServer::factory(
new HttpServer(
new WsServer(new DemoChat())
),
8080
);

echo "[" . date('H:i:s') . "] WebSocket server started at ws://127.0.0.1:8080\n";
$server->run();