avatar

mdo

Hello

  • 首页
  • 知识库
  • 归档
  • 标签
  • 关于
主页 think-swoole4.0通过监听端口自定义rpc服务 
文章

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

发表于 2026-06-14 更新于 2026-06- 14
作者 mdo
8~10 分钟 阅读

在 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();

技术
许可协议:  CC BY 4.0
分享

相关文章

7月 26, 2026

完美地解决 TP3 老系统数据的平滑读取

为了彻底、完美地解决 TP3 老系统数据的平滑读取,必须解决两个核心痛点: TP3 的盲猜反序列化机制(标量存原样,数组/对象存原生 serialize,同时兼容 json)。 TP3 与 TP6 的缓存前缀(Prefix)不一致。 以下是为你量身定制的终极落地解决方案,通

7月 26, 2026

thinkphp3 redis序列化和反序列化

在老系统重构迁移至 ThinkPHP 6 (TP6) 的过程中,ThinkPHP 3 (TP3) 的 Redis 序列化历史遗留问题是最核心的连环坑之一。 TP3 的 S('key', $value) 缓存方法和底层 Redis 驱动,在存储非字符串(如数组、对象)时,有一套独特的序列化行为。如果不

7月 24, 2026

Table 空间极易发生哈希冲突并溢出

既然你没有在业务中主动调用 Room,只使用了全局广播,那么这个问题就非常明确了:即使你不用房间功能,think-swoole 只要开启了 WebSocket,底层就会强行初始化并注入一个名为 Room 的驱动组件。 [1] 框架底层默认使用 table 类型来作为 Room 的存储介质。当进行全局

下一篇

think-swoole 4.0和3.0版本区别

上一篇

RpcService.php receive 没有收到数据

最近更新

  • 完美地解决 TP3 老系统数据的平滑读取
  • thinkphp3 redis序列化和反序列化
  • Table 空间极易发生哈希冲突并溢出
  • 将监控程序直接跑在云端
  • AI 驱动型 Facebook 群组关键词监控 Chrome 浏览器插件

热门标签

API CodeGeex Gitkraken Management Manticore Premiere Sublime Swoole ThinkPHP ThinkPHP5

目录

©2026 mdo. 保留部分权利。