开发服务端

新增一个长链接服务端,要先从配置增加新的长链接端口。然后编写启动workerman后的事件回调处理。下面从新增一个长链接服务端为例。

以下全部为示例说明,系统内部已全部完成这些功能逻辑的处理。

增加新的长链接配置

修改conf/workerman.php

return [
    //...

    'kefu' => [
        //协议
        'protocol' => 'websocket',
        //监听地址
        'ip' => '0.0.0.0',
        //监听端口,端口一定不能和配置文件内的有重复
        'port' => 20004,
        //设置当前Worker实例启动多少个进程
        'serverCount' => 1,
    ]
];

增加kefu服务端socket事件处理文件

创建crmeb/services/workerman/kefu/KefuService.php

namespace crmeb\services\workerman\kefu;

use Channel\Client;
use Workerman\Connection\TcpConnection;
use Workerman\Lib\Timer;
use Workerman\Worker;


class KefuService
{

    /**
     * @var Worker
     */
    protected $worker;

    /**
     * @var TcpConnection[]
     */
    protected $connections = [];

    /**
     * @var TcpConnection[]
     */
    protected $user = [];

    /**
     * @var KefuHandle
     */
    protected $handle;

    /**
     * @var Response
     */
    protected $response;

    /**
     * @var int
     */
    protected $timer;

    public function __construct(Worker $worker)
    {
        $this->worker = $worker;
        $this->handle = new KefuHandle($this);
        $this->response = new Response();
    }

    public function setUser(TcpConnection $connection)
    {
        //$connection->user;在crmeb\services\workerman\kefu\KefuHandle.php的login方法内设置
        $this->user[$connection->user['id']] = $connection;
    }

    //需要完成连接成功事件
    public function onConnect(TcpConnection $connection)
    {

    }

    //需要完成消息发送事件
    public function onMessage(TcpConnection $connection, $res)
    {

    }

    //workerman启动事件
    public function onWorkerStart(Worker $worker)
    {
            //可以写内部通讯事件
    }

    //需要完成关闭长链接事件
    public function onClose(TcpConnection $connection)
    {

    }

}

增加kefu服务端socket消息事件回调文件

创建crmeb/services/workerman/kefu/KefuHandle.php

namespace crmeb\services\workerman\kefu;

use Workerman\Connection\TcpConnection;
use crmeb\services\workerman\Response;

class KefuHandle
{
    /**
     * @var KefuService
     */
    protected $service;

    /**
     * ChatHandle constructor.
     * @param KefuService $service
     */
    public function __construct(KefuService &$service)
    {
        $this->service = &$service;
    }

    public function login(TcpConnection &$connection, array $res, Response $response)
    {
        // 获取到用户信息,赋值给$connection
        $userInfo = [];
        $connection->user = $userInfo;
        //设置在crmeb\services\workerman\kefu\KefuService.php内的setUser方法
        $this->service->setUser($connection);
    }
}

修改命令行启动文件,增加kefu长链接回调事件

修改crmeb\command\Workerman.php

use crmeb\services\workerman\kefu\KefuService;

class Workerman extends Command
{

    protected $kefuWorkerServer;

    protected function execute(Input $input, Output $output)
    {

        //...

        //增加启动kefu的worker进程
        if (!$server || $server == 'kefu')  {
            var_dump('kefu');

            $this->kefuWorkerServer = new Worker(
                $this->config['kefu']['protocol'] . '://' . $this->config['kefu']['ip'] . ':' . $this->config['kefu']['port'], 
                $context
            );
            $this->kefuWorkerServer->count = $this->config['kefu']['serverCount'];
            if ($confing['wss_open']) {
                $this->kefuWorkerServer->transport = 'ssl';
            }

        }

         //...
        try {
            Worker::runAll();
        } catch (\Exception $e) {
            $output->warning($e->getMessage());
        }
    }

    protected function bindHandle()
    {
            //...
            //设置客服长链接回调事件处理
            if (!is_null($this->kefuWorkerServer)) {
                $chatServer = new KefuService($this->kefuWorkerServer, $this->channelServer);
                $this->kefuWorkerServer->onConnect = [$chatServer, 'onConnect'];
                $this->kefuWorkerServer->onMessage = [$chatServer, 'onMessage'];
                $this->kefuWorkerServer->onWorkerStart = [$chatServer, 'onWorkerStart'];
                $this->kefuWorkerServer->onClose = [$chatServer, 'onClose'];
        }
    }

}

启动客服命令

如果要在windows上运行,还需要修改workerman.bat

chcp 65001
start "Chat Serve" /b php think workerman start chat
start "Admin Serve" /b php think workerman start admin
start "Kefu Serve" /b php think workerman start kefu
start "Time Task" /b php think timer start
php think workerman start channel

单个命令启动

php think workerman start kefu

守护进程启动

php think workerman start kefu --d

长链接发送不同的消息类型处理

需要修改上面创建的crmeb/services/workerman/kefu/KefuHandle.php

use Workerman\Connection\TcpConnection;
use crmeb\services\workerman\Response;

class KefuHandle
{
    /**
     * @var KefuService
     */
    protected $service;

    /**
     * ChatHandle constructor.
     * @param KefuService $service
     */
    public function __construct(KefuService &$service)
    {
        $this->service = &$service;
    }


    //chat方法名称,属于消息类型名称,可以自定义
    public function chat(TcpConnection &$connection, array $res, Response $response)
    {
        //可以获得当前登录的用户信息
        $connection->user;

        //$res为前台发送的消息

        //参数1位返回给前台的消息类型
        //参数2位返回给前台的消息内容
        $response->send('message', ['']);
    }

}