Heim > PHP-Framework > Workerman > Hauptteil

Wie Workerman das Chat-System implementiert

Freigeben: 2019-12-12 14:03:12
Original
3462 Leute haben es durchsucht

Wie Workerman das Chat-System implementiert

Thinkphp5.1 installieren

composer create-project topthink/think=5.1.x-dev tp5andWorkerman
Nach dem Login kopieren

Think-Worker installieren

composer require topthink/think-worker=2.0.*
Nach dem Login kopieren

Workerman direkt installieren

composer require workerman/workerman
Nach dem Login kopieren

(2) Sehen wir uns an it first think-worker code

config/worker_server.php
Nach dem Login kopieren

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));
        }
    });}
Nach dem Login kopieren

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);
    }}
Nach dem Login kopieren

Ä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);
    }};
Nach dem Login kopieren

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();};
Nach dem Login kopieren

Websocket-Verbindungszeit abrufen:

$worker->onMessage = function ($connection, $data)use($worker) {
    $login_time = $connection->login_time;};
Nach dem Login kopieren

Daraus können wir erkennen, dass wir Daten an ein Attribut der $connection-Verbindung binden können, For Beispiel:

$connection->uid = $uid;
Nach dem Login kopieren

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}));};
Nach dem Login kopieren
$worker->onMessage = function ($connection, $data)use($worker) {
    $origin = json_decode($data,true);
    if(array_key_exists('bind',$origin)){
        $connection->uid = $origin['uid'];
    }};
Nach dem Login kopieren

(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);
        }
    }};
Nach dem Login kopieren

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));
Nach dem Login kopieren

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);
    }
};
Nach dem Login kopieren

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(&#39;<li>&#39;+your.content+&#39;</li>&#39;);
    }
};
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!