Maison  >  Article  >  cadre php  >  Utilisez Workman pour créer une salle de discussion

Utilisez Workman pour créer une salle de discussion

步履不停
步履不停original
2019-06-21 14:52:236184parcourir

Utilisez Workman pour créer une salle de discussion

Pourquoi écrivez-vous cet article ?

J'ai appris Workman plusieurs fois, mais j'ai échoué à chaque fois (je n'ai pas atteint la fonction souhaitée, pardonnez-moi d'être stupide). Mais cette fois, il a également fallu plusieurs heures pour mettre en œuvre des fonctions qui n'avaient pas été réalisées auparavant. En fait, il existe deux fonctions simples : l'envoi de messages en tête-à-tête et la diffusion de messages (chat de groupe). Cette fonction est implémentée avec swoole depuis longtemps, et c'est aussi parce que j'ai toujours voulu utiliser think-worker. Pensez-y, vous devez encore le découvrir vous-même. Le framework que d'autres ont créé est peut-être castré. version.

Ne me demandez pas pourquoi je n'utilise pas swoole, car Workman peut fonctionner sous Windows.

(1) Tout d’abord, parlons brièvement de l’installation de thinkphp+workerman.

Installez thinkphp5.1

composer create-project topthink/think=5.1.x-dev tp5andworkman

Installez think-worker

composer require topthink/think-worker=2.0.*

Installez workman directement

composer require workerman/workerman

(2) Regardons C'est d'abord le code think-worker

  • config/worker_server.php

  • Prenons d'abord un exemple du serveur diffusant un message toutes les 10 secondes Diffusez régulièrement un message

'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));
        }
    });
}

Mais pendant onMessage, nous ne pouvons pas obtenir l'objet $worker, nous ne pouvons donc pas diffuser le message.

'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);
    }
}

J'ai essayé différentes méthodes, mais aucune ne semblait fonctionner

'onMessage'      => function ($connection, $data)use($worker) {
    // 这样是获取不到 $worker 对象的
    // ...省略代码
}

Nous ne pouvons donc qu'abandonner le framework think-worker que thinkphp a encapsulé pour nous, et devoir l'écrire nous-mêmes (ou modifier le code interne du framework)

Modifier le code à l'intérieur du framework : /vendor/topthink/think-worker/src/command/Server.php, principalement pour ajouter vous-même la méthode onMessage

use() consiste à passer des variables externes à la fonction pour un usage interne , ou utilisez 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);
    }
};

De cette façon, nous pouvons obtenir l'objet $worker

$worker->onMessage = function ($connection, $data)use($worker) { ... }

(3) $connection lie uid

En fait, vous avez déjà vu que $ worker->connections obtient les connexions de tous les utilisateurs actuels, et connections est l'un des liens.

Enregistrer le temps de connexion au websocket :

$worker->onConnect = function ($connection) {
    $connection->login_time = time();
};

Obtenir le temps de connexion au websocket :

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

À partir de là, nous pouvons voir que nous pouvons lier des données à un attribut de la connexion $connection, pour exemple :

$connection->uid = $uid;

Lorsque le côté JavaScript se connecte avec succès au serveur websocket, il envoie immédiatement son uid au serveur pour liaison :

$worker->onMessage = function ($connection, $data)use($worker) {
    $origin = json_decode($data,true);
    if(array_key_exists('bind',$origin)){
        $connection->uid = $origin['uid'];
    }
};

(4) Message Unicast, c'est-à-dire personnalisé envoi

$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);
        }
    }
};

À ce stade, le message d'envoi d'objet personnalisé basé sur workman est terminé.

Puisque le fichier php est stocké dans composer, il vous suffit de copier le fichier, de le placer dans application/command, de modifier l'espace de noms et de l'enregistrer dans votre propre projet

(5) Comparaison avec swoole

1. Workman peut s'exécuter sur le système Windows, mais pas swoole.

2. Workman : $worker->connections obtient toutes les connexions, $connection->id obtient son propre identifiant de connexion swoole : $server->connections obtient toutes les connexions, $connection->fd ; Obtenez votre propre identifiant de connexion.

3. La méthode onWorkerStart est exécutée lorsque Workman démarre, et le minuteur peut y être écrit ; swoole utilise WorkerStart pour démarrer le minuteur.

Pour les salons de discussion ou les minuteries, Workman est encore plus pratique.

Pour plus d'articles techniques liés à ThinkPHP, veuillez visiter la colonne Tutoriel d'utilisation de ThinkPHP pour apprendre !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn