RpcService.php receive 没有收到数据

我来分析一下为什么 RPC 服务端的 receive 事件没有收到数据。通过查看代码,我发现了几个关键问题:

  1. 在 RpcClient.php 中,数据发送使用了 JsonProtocol::encode() 进行编码,它会在 JSON 数据后添加换行符 "\n" 作为结束标记。

  2. 在 RpcService.php 中,服务端配置了固定包头协议(代码被注释掉了),但实际处理时没有使用任何协议解析。

  3. 在 RpcService.php 中,receive 事件处理器直接接收原始数据,没有处理可能的粘包问题。

解决方案:

  1. 首先需要取消注释并配置服务端的协议设置:

代码位置:RpcService.php

修改为:

// 设置 RPC 端口的独立参数(使用换行符作为分包协议)
$rpcPort->set([
    'open_eof_check' => true,
    'package_eof' => "\n",
    'open_eof_split' => true,
]);
  1. 修改 receive 事件处理逻辑,添加数据验证:

代码位置:RpcService.php

修改为:

$rpcPort->on('receive', function (SwooleServer $serv, int $fd, int $reactorId, string $data)
{
    if (empty($data)) {
        return;
    }
    file_put_contents(runtime_path() . '/rpc.log', date('Y-m-d H:i:s') . " Received: " . $data . "\n", FILE_APPEND);
    $this->handleRpcRequest($serv, $fd, $reactorId, $data);
});
  1. 在 handleRpcRequest 方法中添加更详细的日志记录:

代码位置:RpcService.php

修改为:

protected function handleRpcRequest(SwooleServer $serv, int $fd, $reactorId, string $data)
{
    try {
        // 记录接收到的原始数据
        file_put_contents(runtime_path() . '/rpc.log', date('Y-m-d H:i:s') . " Processing: " . $data . "\n", FILE_APPEND);
        
        // 去掉换行符
        $data = trim($data);
        
        // 解析 JSON 数据
        $request = json_decode($data, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \Exception("Invalid JSON data: " . json_last_error_msg());
        }
  1. 确保响应数据也添加换行符:

代码位置:RpcService.php

修改为:

// 响应客户端(添加换行符作为结束标记)
$sendData = json_encode($response) . "\n";
return $serv->send($fd, $sendData, $reactorId);

这些修改的主要目的是:

  1. 配置 Swoole 使用换行符作为分包协议,确保正确处理数据包边界

  2. 添加数据验证和错误处理

  3. 增加详细的日志记录,便于调试

  4. 确保服务端和客户端使用相同的协议格式

修改后,请检查 runtime_path() . '/rpc.log' 文件,查看是否有数据接收记录。如果仍然没有数据,可能需要检查:

  1. 客户端连接的地址和端口是否正确

  2. 防火墙是否阻止了连接

  3. Swoole 服务是否正常启动并监听在指定端口