Heim > Artikel > PHP-Framework > Verwenden Sie Workman, um einen Chatroom zu erstellen
Warum schreibst du diesen Artikel?
Ich habe Workman mehrmals gelernt, bin aber jedes Mal gescheitert (ich habe die gewünschte Funktion nicht erreicht, verzeihen Sie mir, dass ich dumm bin). Aber auch die Umsetzung von Funktionen, die es zuvor noch nicht gab, dauerte dieses Mal mehrere Stunden. Tatsächlich gibt es zwei einfache Funktionen: das Senden von Nachrichten eins zu eins und das Senden von Nachrichten (Gruppenchat). Diese Funktion wurde schon lange mit swoole implementiert, und das liegt auch daran, dass ich schon immer Think-Worker verwenden wollte. Das Framework, das andere erstellt haben, ist möglicherweise noch nicht vollständig Version.
Fragen Sie mich nicht, warum ich Swoole nicht verwende, denn Workman kann unter Windows ausgeführt werden.
(1) Lassen Sie uns zunächst kurz über die Installation von thinkphp+workerman sprechen.
Thinkphp5.1 installieren
composer create-project topthink/think=5.1.x-dev tp5andworkman
Think-Worker installieren
composer require topthink/think-worker=2.0.*
Workman direkt installieren
composer require workerman/workerman
(2) Sehen wir uns an Zuerst denke ich an den Worker-Code
config/worker_server.php
Nehmen wir zunächst ein Beispiel eines Servers, der eine Nachricht sendet alle 10 Sekunden Regelmäßig eine Nachricht senden
'onWorkerStart' => function ($worker) { \Workerman\Lib\Timer::add(10, function()use($worker){ // 遍历当前进程所有的客户端连接,发送自定义消息 foreach($worker->connections as $connection){ $send['name'] = '系统信息'; $send['content'] = '这是一个定时任务信息'; $send['time'] = time(); $connection->send(json_encode($send)); } }); }
Aber während onMessage können wir das $worker-Objekt nicht abrufen, sodass wir die Nachricht nicht senden können.
'onMessage' => function ($connection, $data) { $origin = json_decode($data,true); $send['name'] = '广播数据'; $send['content'] = $origin['content']; $message = json_encode($send); foreach($worker->connections as $connection) { $connection->send($message); } }
Ich habe verschiedene Methoden ausprobiert, aber keine schien zu funktionieren
'onMessage' => function ($connection, $data)use($worker) { // 这样是获取不到 $worker 对象的 // ...省略代码 }
Wir können also nur das Think-Worker-Framework aufgeben, das thinkphp für uns gekapselt hat, und müssen es selbst schreiben (oder ändern). interner Code des Frameworks)
Ändern Sie den Code innerhalb des Frameworks: /vendor/topthink/think-worker/src/command/Server.php
, fügen Sie hauptsächlich die onMessage-Methode selbst hinzu
use() dient dazu, externe Variablen zur internen Verwendung an die Funktion zu übergeben, oder verwenden Sie global $worker
$worker = new Worker($socket, $context); $worker->onMessage = function ($connection, $data)use($worker) { $origin = json_decode($data,true); $send['name'] = '广播数据'; $send['content'] = $origin['content']; $send['uid'] = $connection->uid; $message = json_encode($send); foreach($worker->connections as $connection) { $connection->send($message); } };
Auf diese Weise können wir das $worker-Objekt erhalten
$worker->onMessage = function ($connection, $data)use($worker) { ... }
(3) $connection binds uid
In Tatsächlich haben Sie bereits gesehen, dass $ worker->connections die Verbindungen aller aktuellen Benutzer abruft und Verbindungen einer der Links ist.
Websocket-Verbindungszeit aufzeichnen:
$worker->onConnect = function ($connection) { $connection->login_time = time(); };
Websocket-Verbindungszeit abrufen:
$worker->onMessage = function ($connection, $data)use($worker) { $login_time = $connection->login_time; };
Daraus können wir erkennen, dass wir Daten an ein Attribut der $connection-Verbindung binden können, For Beispiel:
$connection->uid = $uid;
Wenn die JavaScript-Seite erfolgreich eine Verbindung zum Websocket-Server herstellt, sendet sie sofort ihre UID zur Bindung an den Server:
$worker->onMessage = function ($connection, $data)use($worker) { $origin = json_decode($data,true); if(array_key_exists('bind',$origin)){ $connection->uid = $origin['uid']; } };
(4) Unicast-Nachricht, also benutzerdefiniert Senden
$worker->onMessage = function ($connection, $data)use($worker) { $origin = json_decode($data,true); $sendTo = $origin['sendto']; // 需要发送的对方的uid $content = $origin['content']; // 需要发送到对方的内容 foreach($worker->connections as $connection) { if( $connection->uid == $sendTo){ $connection->send($content); } } };
An diesem Punkt ist das benutzerdefinierte Objekt, das eine Nachricht basierend auf Workman sendet, abgeschlossen.
Da die PHP-Datei im Composer gespeichert ist, müssen Sie sie nur kopieren, in application/command
einfügen, den Namespace ändern und in Ihrem eigenen Projekt speichern
(5) Vergleich mit Swoole
1. Workman kann im Windows-System ausgeführt werden, Swoole jedoch nicht.
2. Workman: $worker->connections erhält alle Verbindungen, $connection->id erhält seine eigene Verbindungs-ID; swoole: $server->connections erhält alle Verbindungen, $connection->fd Holen Sie sich Ihre eigene Verbindungs-ID.
3. Die onWorkerStart-Methode wird ausgeführt, wenn Workman startet, und der Timer kann in sie geschrieben werden.
Für Chatrooms oder Timer ist Workman noch bequemer.
Weitere technische Artikel zu ThinkPHP finden Sie in der Spalte Tutorial zur Verwendung von ThinkPHP, um mehr zu erfahren!
Das obige ist der detaillierte Inhalt vonVerwenden Sie Workman, um einen Chatroom zu erstellen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!