كيفية إرسال بيانات إلى عميل معين في Workerman

استخدام worker كخادم، دون استخدام GatewayWorker، كيف يمكن تنفيذ إرسال رسالة إلى مستخدم محدد؟

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

// تهيئة حاوية worker، الاستماع على المنفذ 1234
$worker = new Worker('websocket://workerman.net:1234');
// ==== يجب أن يكون عدد العمليات هنا 1 ====
$worker->count = 1;
// إضافة خاصية جديدة، لحفظ uid إلى الاتصال (uid هو معرف المستخدم أو معرف فريد للعميل)
$worker->uidConnections = array();
// دالة_callback تُنفذ عند تلقي رسالة من عميل
$worker->onMessage = function(TcpConnection $connection, $data)
{
    global $worker;
    // التحقق مما إذا كان العميل الحالي قد تم التحقق منه، أي إذا تم تعيين uid
    if(!isset($connection->uid))
    {
       // إذا لم يتم التحقق، فاعتبر الحزمة الأولى كـ uid (هنا من أجل سهولة العرض، لم يتم إجراء تحقق حقيقي)
       $connection->uid = $data;
       /* حفظ uid إلى اتصال وتسهيل البحث عن الاتصال عبر uid،
        * مما يمكن من دفع البيانات إلى uid معين
        */
       $worker->uidConnections[$connection->uid] = $connection;
       return $connection->send('تسجيل الدخول بنجاح، uid الخاص بك هو ' . $connection->uid);
    }
    // منطق آخر، إرسال إلى uid معين أو بث عالمي
    // افترض أن تنسيق الرسالة هو uid:message، فهذه هي الرسالة الموجهة إلى uid
    // uid هو all عند البث العالمي
    list($recv_uid, $message) = explode(':', $data);
    // بث عالمي
    if($recv_uid == 'all')
    {
        broadcast($message);
    }
    // إرسال إلى uid معين
    else
    {
        sendMessageByUid($recv_uid, $message);
    }
};

// عند قطع اتصال عميل
$worker->onClose = function(TcpConnection $connection)
{
    global $worker;
    if(isset($connection->uid))
    {
        // عند قطع الاتصال، قم بإزالة الخريطة
        unset($worker->uidConnections[$connection->uid]);
    }
};

// دفع البيانات إلى جميع المستخدمين الذين تم التحقق منهم
function broadcast($message)
{
   global $worker;
   foreach($worker->uidConnections as $connection)
   {
        $connection->send($message);
   }
}

// دفع البيانات إلى uid معين
function sendMessageByUid($uid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$uid]))
    {
        $connection = $worker->uidConnections[$uid];
        $connection->send($message);
    }
}

// تشغيل جميع الworkers (في الواقع، تم تعريف واحد فقط)
Worker::runAll();

ملاحظة:

يمكن للمثال أعلاه دفع الرسائل إلى uid، على الرغم من أنه يعمل في عملية واحدة، إلا أنه يدعم حوالي 100,000 مستخدم متصل دون مشاكل.

يرجى ملاحظة أن هذا المثال يعمل فقط في عملية واحدة، مما يعني أن $worker->count يجب أن يكون 1. لدعم تعدد العمليات أو مجموعة خوادم، يلزم استخدام مكون Channel لتنفيذ الاتصال بين العمليات، وتطويرها بسيط للغاية، يمكنك الرجوع إلى مثال دفع مجموعة من مكون Channel.

إذا كنت ترغب في دفع الرسائل إلى العميل من أنظمة أخرى، يمكنك الرجوع إلى دفع في مشاريع أخرى.