think-swoole4.0通过监听端口自定义rpc服务 

think-swoole 4.0(基于 ThinkPHP 6.0)中实现自定义 RPC 服务,最优雅的方式是使用 Swoole 的 多端口监听(Server::addlistener) 功能。通过自定义服务类,你可以在同一个主进程中独立处理 RPC 请求。

以下是具体的实现步骤与代码示例:

第一步:创建自定义 Swoole 服务类

继承 think\swoole\Server 并重写 onWorkerStart 与自定义的 RPC 逻辑。

创建文件 app/swoole/RpcServer.php

php

namespace app\swoole;

use think\swoole\Server;
use Swoole\Server as SwooleServer;

class RpcServer extends Server
{
    /**
     * 重写父类方法,增加端口监听
     * @param SwooleServer $server
     */
    public function onWorkerStart(SwooleServer $server, int $workerId)
    {
        // 监听额外的 9502 端口用于 RPC 服务,协议为 TCP
        $rpcPort = $server->addlistener('0.0.0.0', 9502, SWOOLE_SOCK_TCP);
        
        // 可选:设置 RPC 端口的协议,如 EOF 边界检测或 JSON 解析
        $rpcPort->set([
            'open_length_check'     => true,
            'package_length_type'   => 'N',
            'package_length_offset' => 0,
            'package_body_offset'   => 4,
            'package_max_length'    => 2097152,
        ]);

        // 绑定 RPC 端口的数据接收事件
        $rpcPort->on('receive', function (SwooleServer $server, $fd, $reactorId, $data) {
            $this->handleRpc($server, $fd, $data);
        });

        // 调用父类的 onWorkerStart 保证其他常规业务(如HTTP/Websocket)正常启动
        parent::onWorkerStart($server, $workerId);
    }

    /**
     * 处理 RPC 请求逻辑
     */
    protected function handleRpc(SwooleServer $server, $fd, $data)
    {
        // 1. 解析客户端传来的数据(假设为 JSON 格式)
        $req = json_decode($data, true);
        $method = $req['method'] ?? '';
        $params = $req['params'] ?? [];

        // 2. 路由处理并调用对应逻辑
        $result = $this->dispatch($method, $params);

        // 3. 返回结果给客户端
        $server->send($fd, json_encode($result));
        
        // 4. 短连接处理,处理完关闭连接
        $server->close($fd);
    }

    /**
     * 简单的服务分发逻辑
     */
    protected function dispatch($method, $params)
    {
        // 示例:模拟用户服务
        if ($method === 'getUser') {
            $userId = $params['id'] ?? 0;
            return [
                'code' => 200,
                'message' => 'Success',
                'data' => ['id' => $userId, 'name' => 'ThinkSwoole']
            ];
        }

        return ['code' => 404, 'message' => 'Method Not Found'];
    }
}

请谨慎使用此类代码。

第二步:修改配置文件

修改 config/swoole.php,将 server 指向你刚刚创建的自定义类:

php

return [
    // 将此处替换为你自定义的服务类
    'server'      => '\app\swoole\RpcServer',
    
    // 主服务器监听端口(通常处理 HTTP/WebSocket)
    'host'        => '0.0.0.0',
    'port'        => 80,
    
    // ... 其他配置保持不变 ...
];

请谨慎使用此类代码。

第三步:启动服务

在项目根目录执行以下命令启动 Swoole:

bash

php think swoole

请谨慎使用此类代码。

启动后,主服务会监听默认端口,同时会在内部监听 9502 端口等待 RPC 客户端请求。

第四步:RPC 客户端调用示例

你可以使用任意客户端(如普通的 PHP 脚本、Go 等其他语言)通过 TCP 连接发送 JSON 数据进行测试:

php

// 简单的 PHP 客户端测试脚本
$client = new \Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9502, 0.5)) {
    die("connect failed. Error: {$client->errCode}\n");
}

// 发送 RPC 调用请求
$req = [
    'method' => 'getUser',
    'params' => ['id' => 1001]
];
$client->send(json_encode($req));

// 接收返回数据
echo $client->recv();

$client->close();