Install thinkphp5.1
composer create-project topthink/think=5.1.x-dev tp5andWorkerman
Install think-worker
composer require topthink/think-worker=2.0.*
Workerman 직접 설치
composer require workerman/workerman
(2) 먼저 Think-Worker 코드를 살펴보겠습니다
config/worker_server.php
먼저, 10초마다 메시지 시계는 정기적으로 메시지를 방송합니다
'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)); } });}
하지만 onMessage 중에는 $worker 객체를 얻을 수 없으므로 메시지를 방송할 수 없습니다.
'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); }}
프레임워크 내부의 코드를 수정하세요: /vendor/topthink/think-worker/src/command/Server.php, 주로 onMessage 메서드를 직접 추가하세요
use()는 사용할 함수에 외부 변수를 전달하는 것입니다. 또는 전역 $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); }};
를 사용하면 $worker 객체
$worker->onMessage = function ($connection, $data)use($worker) { ... }
( 3 ) $connection은 uid
에 바인딩되어 있습니다. 실제로 $worker->connections가 모든 현재 사용자의 연결을 얻고 연결이 링크 중 하나라는 것을 이미 살펴보았습니다.
웹소켓 연결 시간 기록:
$worker->onConnect = function ($connection) { $connection->login_time = time();};
웹소켓 연결 시간 가져오기:
$worker->onMessage = function ($connection, $data)use($worker) { $login_time = $connection->login_time;};
데이터를 $connection 연결 속성에 바인딩할 수 있음을 알 수 있습니다. 예:
$connection->uid = $uid;
JavaScript 측이 websocket 서버 성공 후 즉시 바인딩을 위해 서버에 uid를 보냅니다:
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) 유니캐스트 메시지 전송, 즉 커스텀 전송
$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); } }};
이제 Workerman 기반으로 메시지를 보내는 커스텀 객체가 완료되었습니다.
PHP 파일은 작곡가에 저장되어 있으므로 파일을 복사하여 애플리케이션/명령에 넣고 네임스페이스를 수정한 후 자신의 프로젝트에 저장하기만 하면 됩니다.
(5) 채팅 기록 저장
Redis를 사용하여 캐싱은 서버에 거의 영향을 미치지 않으며 기본적으로 응답 시간에 영향을 미치지 않습니다
1. Redis에 채팅 기록을 저장하고 목록 저장소를 사용합니다
$message = json_decode($data,true); // $data为接收到的数据 $redis_instance = Cache::handler(); // TP5代码获取Cache实例 $redis_instance->lPush('message',json_encode($message,JSON_UNESCAPED_UNICODE));
2. 경우에 따라 사용자가 채팅 페이지를 처음(또는 새로 고칠 때) 최근 10개 기록 표시
$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); } };
최근 채팅 기록을 얻을 때 Javascript 처리:
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>'); } };
위 내용은 Workerman이 채팅 시스템을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!