>PHP 프레임워크 >ThinkPHP >Workman을 사용하여 채팅방 만들기

Workman을 사용하여 채팅방 만들기

步履不停
步履不停원래의
2019-06-21 14:52:236244검색

Workman을 사용하여 채팅방 만들기

이 글을 쓰는 이유는 무엇인가요?

워크맨을 여러번 배웠지만 매번 실패했습니다. (원하는 기능을 이루지 못했어요, 바보같아서 용서해주세요). 하지만 이번에도 이전에 수행되지 않았던 기능을 구현하는 데 몇 시간이 걸렸습니다. 실제로 간단한 기능은 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

use()는 외부 변수를 함수에 전달하는 것입니다. 내부용으로 사용하거나 전역 $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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.