Installez thinkphp5.1
composer create-project topthink/think=5.1.x-dev tp5andWorkerman
Installez think-worker
composer require topthink/think-worker=2.0.*
Installez Workerman directement
composer require workerman/workerman
(2) Regardons c'est d'abord think-worker code
config/worker_server.php
Prenons d'abord un exemple de serveur diffusant un message Un message est diffusé régulièrement toutes les 10 secondes
'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, on ne parvient pas à récupérer le $worker. objet, donc impossible de 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); }}
Modifiez 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 à ajouter l'externe Transmettez la variable à 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 est lié à uid
En fait, vous avez déjà vu que $worker ->les connexions obtenues sont les connexions de tous les utilisateurs actuels, et les connexions sont 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 :
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) Message Unicast, c'est-à-dire envoi personnalisé
$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, l'envoi de messages basés sur l'objet personnalisé de Workerman est terminé.
Puisque le fichier php est stocké dans composer, il vous suffit de copier le fichier, de le mettre dans l'application/commande, de modifier l'espace de noms et de l'enregistrer dans votre propre projet
(5) Stockage des enregistrements de discussion
L'utilisation de Redis pour la mise en cache a moins d'impact sur le serveur et n'affecte fondamentalement pas le temps de réponse
1 Stockez les enregistrements de discussion dans Redis et utilisez le stockage de liste
$message = json_decode($data,true); // $data为接收到的数据 $redis_instance = Cache::handler(); // TP5代码获取Cache实例 $redis_instance->lPush('message',json_encode($message,JSON_UNESCAPED_UNICODE));
$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); } };
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>'); } };
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!