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!