Heim  >  Artikel  >  PHP-Framework  >  Wie Workerman das Chat-System implementiert

Wie Workerman das Chat-System implementiert

尚
Original
2019-12-12 14:03:123447Durchsuche

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

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!

Stellungnahme:
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