Example 1

(Requires Workerman version >=3.3.0)

A multi-process (distributed cluster) push system based on Worker, supporting cluster broadcasting and cluster group sending.

start_channel.php
The system can only deploy one start_channel service. Assume it runs on 192.168.1.1.

<?php
use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

// Initialize a Channel server
$channel_server = new Channel\Server('0.0.0.0', 2206);

Worker::runAll();

start_ws.php
The system can deploy multiple start_ws services, assuming they run on 192.168.1.2 and 192.168.1.3.

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// websocket server
$worker = new Worker('websocket://0.0.0.0:4236');
$worker->count=2;
$worker->name = 'pusher';
$worker->onWorkerStart = function($worker)
{
    // Channel client connects to Channel server
    Channel\Client::connect('192.168.1.1', 2206);
    // Use the process id as the event name
    $event_name = $worker->id;
    // Subscribe to worker->id events and register event handlers
    Channel\Client::on($event_name, function($event_data)use($worker){
        $to_connection_id = $event_data['to_connection_id'];
        $message = $event_data['content'];
        if(!isset($worker->connections[$to_connection_id]))
        {
            echo "connection not exists\n";
            return;
        }
        $to_connection = $worker->connections[$to_connection_id];
        $to_connection->send($message);
    });

    // Subscribe to broadcast events
    $event_name = '广播';
    // When a broadcast event is received, send broadcast data to all client connections in the current process
    Channel\Client::on($event_name, function($event_data)use($worker){
        $message = $event_data['content'];
        foreach($worker->connections as $connection)
        {
            $connection->send($message);
        }
    });
};

$worker->onConnect = function(TcpConnection $connection)use($worker)
{
    $msg = "workerID:{$worker->id} connectionID:{$connection->id} connected\n";
    echo $msg;
    $connection->send($msg);
};
Worker::runAll();

start_http.php
The system can deploy multiple start_http services, assuming they run on 192.168.1.4 and 192.168.1.5.

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// Used to handle http requests and push data to any client, requires workerID and connectionID
$http_worker = new Worker('http://0.0.0.0:4237');
$http_worker->name = 'publisher';
$http_worker->onWorkerStart = function()
{
    Channel\Client::connect('192.168.1.1', 2206);
};
$http_worker->onMessage = function(TcpConnection $connection, $request)
{
    // Compatible with workerman4.x 5.x
    if (!is_array($request)) {
        $get = $request->get();
    }
    $connection->send('ok');
    if(empty($get['content'])) return;
    // To push data to a specific connection in a specific worker process
    if(isset($get['to_worker_id']) && isset($get['to_connection_id']))
    {
        $event_name = $get['to_worker_id'];
        $to_connection_id = $get['to_connection_id'];
        $content = $get['content'];
        Channel\Client::publish($event_name, array(
           'to_connection_id' => $to_connection_id,
           'content'          => $content
        ));
    }
    // For global broadcast data
    else
    {
        $event_name = '广播';
        $content = $get['content'];
        Channel\Client::publish($event_name, array(
           'content'          => $content
        ));
    }
};

Worker::runAll();

Testing

  1. Start the services on each server.

  2. Connect the client to the server.

Open Chrome, press F12 to open the debug console, and enter (or place the following code in an HTML page to run it with js)

// You can also connect to ws://192.168.1.3:4236
ws = new WebSocket("ws://192.168.1.2:4236");
ws.onmessage = function(e) {
    alert("Received message from server: " + e.data);
};
  1. Push data through the HTTP interface.

Access the URL http://192.168.1.4:4237/?content={$content} or http://192.168.1.5:4237/?content={$content} to push the $content data to all client connections.

Access the URL http://192.168.1.4:4237/?to_worker_id={$worker_id}&to_connection_id={$connection_id}&content={$content} or http://192.168.1.5:4237/?to_worker_id={$worker_id}&to_connection_id={$connection_id}&content={$content} to push the $content data to a specific client connection in a specific worker process.

Note: During testing, replace {$worker_id} {$connection_id} and {$content} with actual values.