Heim > Artikel > PHP-Framework > Wie Workerman das Chat-System implementiert
Thinkphp5.1 installieren
composer create-project topthink/think=5.1.x-dev tp5andWorkerman
Think-Worker installieren
composer require topthink/think-worker=2.0.*
Workerman direkt installieren
composer require workerman/workerman
(2) Sehen wir uns an it first think-worker code
config/worker_server.php
Nehmen wir zunächst ein Beispiel eines Servers, der eine Nachricht sendet. Eine Nachricht wird regelmäßig alle 10 Sekunden gesendet
'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 den $worker nicht abrufen Objekt, daher kann die Nachricht nicht gesendet werden.
'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); }}
Ändern Sie den Code innerhalb des Frameworks: /vendor/topthink/think-worker/src/command/Server.php, hauptsächlich, um die onMessage-Methode selbst hinzuzufügen.
use() dient zum Hinzufügen die externe Übergeben Sie die Variable zur internen Verwendung an die Funktion 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 ist an uid gebunden
Tatsächlich haben Sie diesen $worker bereits gesehen ->Verbindungen werden erhalten, sind die Verbindungen aller aktuellen Benutzer, und Verbindungen ist einer der Links.
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:
var uid = 600;ws.onopen = function() { ws.send(JSON.stringify({bind:'yes',uid:uid}));};
$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, d. h. benutzerdefiniertes 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); } }};
Zu diesem Zeitpunkt ist das Senden von Nachrichten basierend auf dem benutzerdefinierten Objekt von Workerman abgeschlossen.
Da die PHP-Datei im Composer gespeichert ist, müssen Sie die Datei nur kopieren, in die Anwendung/den Befehl einfügen, den Namespace ändern und sie in Ihrem eigenen Projekt speichern
(5) Speichern von Chat-Aufzeichnungen
Die Verwendung von Redis zum Caching hat weniger Auswirkungen auf den Server und hat grundsätzlich keinen Einfluss auf die Antwortzeit
1. Speichern Sie Chat-Aufzeichnungen in Redis und verwenden Sie den Listenspeicher
$message = json_decode($data,true); // $data为接收到的数据 $redis_instance = Cache::handler(); // TP5代码获取Cache实例 $redis_instance->lPush('message',json_encode($message,JSON_UNESCAPED_UNICODE));
2. In manchen Fällen werden beim ersten Chatten (oder Aktualisieren) der Chat-Seite die letzten 10 Datensätze angezeigt
$redis_instance = Cache::handler(); // TP5代码获取Cache实例 $worker->onConnect = function ($connection)use($redis_instance) { $length = $redis_instance->lLen('message'); if($length > 0){ $send['recently'] = array_reverse($redis_instance->lRange('message', 0, 10)); $send['state'] = 200; $message = json_encode($send,JSON_UNESCAPED_UNICODE); $connection->send($message); }else{ $send['state'] = 204; $send['recently'] = []; $send['msg'] = '暂无聊天记录'; $message = json_encode($send,JSON_UNESCAPED_UNICODE); $connection->send($message); } };
Wenn Javascript die letzten Chat-Datensätze abruft, werden diese verarbeitet:
ws.onmessage = function(e) { var your = JSON.parse(e.data); if(your.recently){ // 初次打开页面,渲染最近10条聊天记录 $.each(your.recently,function(index,item){ item = JSON.parse(item); // TODO:遍历渲染页面 }); }else{ // 处理其他消息 msglist.append('<li>'+your.content+'</li>'); } };
Empfohlen: Workerman-Tutorial
Das obige ist der detaillierte Inhalt vonWie Workerman das Chat-System implementiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!