مثال 1

(مطلوب نسخة Workerman >= 3.3.0)

نظام دفع متعدد العمليات (مجموعة موزعة) مبني على Worker، إرسال جماعي من المجموعة، بث من المجموعة.

start_channel.php
يمكن نشر خدمة واحدة فقط من نوع start_channel في النظام بالكامل. افترض أنها تعمل على 192.168.1.1.

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

// تهيئة خادم Channel
$channel_server = new Channel\Server('0.0.0.0', 2206);

Worker::runAll();

start_ws.php
يمكن نشر عدة خدمات من نوع start_ws في النظام بالكامل، افترض أنها تعمل على 192.168.1.2 و 192.168.1.3 على خادمين.

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

// خادم websocket
$worker = new Worker('websocket://0.0.0.0:4236');
$worker->count=2;
$worker->name = 'pusher';
$worker->onWorkerStart = function($worker)
{
    // عميل Channel يتصل بخادم Channel
    Channel\Client::connect('192.168.1.1', 2206);
    // استخدام معرف العملية الخاصة كاسم للحدث
    $event_name = $worker->id;
    // الاشتراك في حدث worker->id وتسجيل دالة معالجة الحدث
    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 "الاتصال غير موجود\n";
            return;
        }
        $to_connection = $worker->connections[$to_connection_id];
        $to_connection->send($message);
    });

    // الاشتراك في حدث البث
    $event_name = 'بث';
    // عند تلقي حدث البث، إرسال بيانات البث إلى جميع اتصالات العملاء في العملية الحالية
    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} متصل\n";
    echo $msg;
    $connection->send($msg);
};
Worker::runAll();

start_http.php
يمكن نشر عدة خدمات من نوع start_http في النظام بالكامل، افترض أنها تعمل على 192.168.1.4 و 192.168.1.5 على خادمين.

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

// لمعالجة طلبات http، ودفع البيانات إلى أي عميل يتطلب معرفة workerID و 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)
{
    // متوافق مع workerman4.x 5.x
    if (!is_array($request)) {
        $get = $request->get();
    }
    $connection->send('ok');
    if(empty($get['content'])) return;
    // يعني دفع البيانات إلى اتصال معين في عملية worker معينة
    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
        ));
    }
    // يعني بيانات البث العامة
    else
    {
        $event_name = 'بث';
        $content = $get['content'];
        Channel\Client::publish($event_name, array(
           'content'          => $content
        ));
    }
};

Worker::runAll();

اختبار

  1. تشغيل الخدمات على كل خادم.

  2. اتصال العميل بالخادم.

افتح متصفح chrome، واضغط على F12 لفتح وحدة التحكم، ثم أدخل في قسم Console (أو ضع الكود أدناه في صفحة html باستخدام js):

// يمكن أيضًا الاتصال بـ ws://192.168.1.3:4236
ws = new WebSocket("ws://192.168.1.2:4236");
ws.onmessage = function(e) {
    alert("استلام رسالة من الخادم: " + e.data);
};
  1. دفع البيانات من خلال استدعاء واجهة http.

زيارة url http://192.168.1.4:4237/?content={$content} أو http://192.168.1.5:4237/?content={$content} لدفع بيانات $content إلى جميع اتصالات العملاء.

زيارة url http://192.168.1.4:4237/?to_worker_id={$worker_id}&to_connection_id={$connection_id}&content={$content} أو http://192.168.1.5:4237/?to_worker_id={$worker_id}&to_connection_id={$connection_id}&content={$content} لدفع بيانات $content إلى اتصال عميل معين في عملية worker معينة.

ملاحظة: أثناء الاختبار، استبدل {$worker_id} و {$connection_id} و {$content} بالقيم الفعلية.