이 글을 쓰는 이유는 무엇인가요?
워크맨을 여러번 배웠지만 매번 실패했습니다. (원하는 기능을 이루지 못했어요, 바보같아서 용서해주세요). 하지만 이번에도 이전에 수행되지 않았던 기능을 구현하는 데 몇 시간이 걸렸습니다. 실제로 간단한 기능은 1대1 메시지 보내기와 메시지 방송(그룹 채팅) 두 가지가 있습니다. 이 기능은 오랫동안 swoole로 구현해 왔고, 늘 Think-Worker를 사용하고 싶었기 때문이기도 합니다. 버전.
workman은 Windows에서 실행할 수 있기 때문에 왜 swoole을 사용하지 않는지 묻지 마십시오.
(1) 먼저 thinkphp+workerman 설치에 대해 간략히 설명하겠습니다.
thinkphp5.1 설치
composer create-project topthink/think=5.1.x-dev tp5andworkman
install think-worker
composer require topthink/think-worker=2.0.*
workman 직접 설치
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); } }
다양한 방법을 시도했지만 아무것도 작동하지 않는 것 같았습니다
'onMessage' => function ($connection, $data)use($worker) { // 这样是获取不到 $worker 对象的 // ...省略代码 }
그래서 thinkphp가 우리를 위해 캡슐화한 think-worker 프레임워크를 버리고 직접 작성해야 합니다(또는 프레임워크의 내부 코드를 수정해야 합니다)
수정 프레임워크의 내부 코드: /vendor/topthink/think-worker/src/command/Server.php
, 주로 onMessage 메소드를 직접 추가하세요/vendor/topthink/think-worker/src/command/Server.php
,主要是把 onMessage 方法自己加进去
use() 就是把外部变量传递到函数内部使用,或者使用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); } };
这样,我们就能够获取到 $worker 对象了
$worker->onMessage = function ($connection, $data)use($worker) { ... }
(3)$connection 绑定 uid
其实你早都已经看出,$worker->connections 获取到的是当前所有用户的连接,connections 即为其中一个链接。
记录websocket连接时间:
$worker->onConnect = function ($connection) { $connection->login_time = time(); };
获取websocket连接时间:
$worker->onMessage = function ($connection, $data)use($worker) { $login_time = $connection->login_time; };
由此可以看出,我们可以把数据绑定到 $connection 连接的一个属性,例如:
$connection->uid = $uid;
当JavaScript端在连接websocket服务器成功后,即把自己的 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); } } };
到此,已经完成基于 workman 的自定义对象发送消息。
由于该php文件存放于composer中,只需要把该文件复制出来,放到application/command
전역 $worker
rrreee를 사용하세요. 이런 식으로 $worker 개체
rrreee
를 얻을 수 있습니다. (3) $connection은 uid
를 바인드합니다. $worker->connections 얻은 것은 현재 모든 사용자의 연결이고 연결은 링크 중 하나입니다. 웹소켓 연결 시간 기록:rrreee
웹소켓 연결 시간 가져오기:rrreee데이터를 $connection 연결 속성에 바인딩할 수 있음을 알 수 있습니다. 예: rrreeeJavaScript 측이 websocket 서버 성공 후 즉시 바인딩을 위해 서버에 uid를 보냅니다. rrreee (4) 유니캐스트 메시지, 즉 사용자 지정 보내기 rrreee
이 시점에서 workman 기반 사용자 지정 개체 메시지가 완성되었습니다. 🎜🎜php 파일은 작곡가에 저장되어 있으므로 파일을 복사해서application/command
에 넣고 네임스페이스를 수정한 후 자신의 프로젝트에 저장하기만 하면 됩니다🎜🎜🎜 (5) 비교 swoole🎜🎜🎜1. Workman은 Windows 시스템에서 실행할 수 있지만 swoole은 실행할 수 없습니다. 🎜🎜2. workman: $worker->connections는 모든 연결을 가져오고, $connection->id는 자체 연결 ID를 가져옵니다. $server->connections는 모든 연결을 가져오고, $connection->fd는 자체 연결을 가져옵니다. ID. 🎜🎜3. workman이 시작될 때 onWorkerStart 메서드가 실행되며 swoole은 WorkerStart를 사용하여 타이머를 시작할 수 있습니다. 🎜🎜대화방이나 타이머는 여전히 워크맨이 더 편리해요. 🎜🎜🎜ThinkPHP 관련 기술 기사를 더 보려면 🎜🎜🎜ThinkPHP 사용 튜토리얼🎜🎜🎜 칼럼을 방문하여 알아보세요! 🎜🎜위 내용은 Workman을 사용하여 채팅방 만들기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!