So senden Sie Daten an einen bestimmten Client in Workerman

Wie können Sie mit einem Worker-Server, ohne GatewayWorker, eine Nachricht an einen bestimmten Benutzer senden?

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

// Initialisieren Sie einen Worker-Container und hören Sie auf Port 1234
$worker = new Worker('websocket://workerman.net:1234');
// ==== Hier muss die Anzahl der Prozesse unbedingt auf 1 gesetzt werden ====
$worker->count = 1;
// Fügen Sie eine neue Eigenschaft hinzu, um die Zuordnung von uid zu Verbindung zu speichern (uid ist die Benutzer-ID oder die eindeutige Kennung des Clients)
$worker->uidConnections = array();
// Callback-Funktion, die ausgeführt wird, wenn ein Client eine Nachricht sendet
$worker->onMessage = function(TcpConnection $connection, $data)
{
    global $worker;
    // Überprüfen, ob der aktuelle Client bereits authentifiziert ist, d.h. ob eine uid gesetzt ist
    if(!isset($connection->uid))
    {
       // Wenn nicht authentifiziert, behandeln Sie das erste Paket als uid (hier zur Vereinfachung wird keine echte Überprüfung vorgenommen)
       $connection->uid = $data;
       /* Speichern Sie die Zuordnung von uid zu Verbindung, sodass die Verbindung einfach über uid gefunden werden kann,
        * um Daten an eine bestimmte uid zu senden
        */
       $worker->uidConnections[$connection->uid] = $connection;
       return $connection->send('Login erfolgreich, Ihre uid ist ' . $connection->uid);
    }
    // Andere Logik, Daten an eine spezifische uid senden oder global broadcast
    // Angenommen, das Nachrichtenformat ist uid:message, dann wird message an uid gesendet
    // wenn uid all ist, ist es ein globaler Broadcast
    list($recv_uid, $message) = explode(':', $data);
    // Globaler Broadcast
    if($recv_uid == 'all')
    {
        broadcast($message);
    }
    // Senden an eine bestimmte uid
    else
    {
        sendMessageByUid($recv_uid, $message);
    }
};

// Wenn eine Verbindung zu einem Client geschlossen wird
$worker->onClose = function(TcpConnection $connection)
{
    global $worker;
    if(isset($connection->uid))
    {
        // Entfernen Sie die Zuordnung, wenn die Verbindung geschlossen wird
        unset($worker->uidConnections[$connection->uid]);
    }
};

// Daten an alle authentifizierten Benutzer senden
function broadcast($message)
{
   global $worker;
   foreach($worker->uidConnections as $connection)
   {
        $connection->send($message);
   }
}

// Daten an uid senden
function sendMessageByUid($uid, $message)
{
    global $worker;
    if(isset($worker->uidConnections[$uid]))
    {
        $connection = $worker->uidConnections[$uid];
        $connection->send($message);
    }
}

// Führen Sie alle Worker aus (in Wirklichkeit wurde derzeit nur einer definiert)
Worker::runAll();

Hinweis:

Das obige Beispiel kann eine gezielte Zustellung an uid ermöglichen. Obwohl es sich um einen einzelnen Prozess handelt, sind bis zu 100.000 gleichzeitige Verbindungen kein Problem.

Bitte beachten Sie, dass dieses Beispiel nur für einen einzelnen Prozess gilt, was bedeutet, dass $worker->count auf 1 gesetzt sein muss. Um mehrere Prozesse oder einen Server-Cluster zu unterstützen, ist es notwendig, die Channel-Komponente zu verwenden, um die Kommunikation zwischen Prozessen abzuwickeln. Die Entwicklung ist ebenfalls sehr einfach und Sie können sich das Beispiel für die Channel-Komponenten-Clusternachricht ansehen.

Wenn Sie Nachrichten aus anderen Systemen an den Client senden möchten, können Sie die Nachrichtenübermittlung in anderen Projekten lesen.