登录/注册

gRPC 服务

gRPC 官方文档中的 quickstart – php, 很容易给 PHPer 产生误导, 按照官网的文档, 运行起来 gRPC 服务就很麻烦, 更不用说整套的 RPC 服务了.

推荐阅读 tech| 再探 grpc, 讲解了在 PHP 中实现 gRPC 相关基础知识.

hyperf 对 gRPC 支持做了更进一步的封装, hyperf-skeleton 项目为例, 详细讲解整个步骤:

  • .proto 文件以及相关配置实例
  • gRPC server 示例
  • gRPC client 示例

.proto 文件以及相关配置实例

  • 定义好 proto 文件 grpc.proto
syntax = "proto3";

package grpc;

service hi {
    rpc sayHello (HiUser) returns (HiReply) {
    }
}

message HiUser {
    string name = 1;
    int32 sex = 2;
}

message HiReply {
    string message = 1;
    HiUser user = 2;
}
# 使用 linux 包管理工具安装 protoc, 下面以 alpine 为例, 也可以参考 hyper-skeleton 下的 Dockerfile
apk add protobuf

# 使用 protoc 自动生成代码
protoc --php_out=grpc/ grpc.proto

# tree grpc
grpc
├── GPBMetadata
│   └── Grpc.php
└── Grpc
    ├── HiReply.php
    └── HiUser.php
  • 配置 composer.json, 使用 grpc/ 下代码的自动加载. 如果 proto 文件中使用不同的 package 设置, 或者使用了不同的目录, 进行相应调整即可,添加之后执行 composer dump-autoload 使自动加载生效
"autoload": {
    "psr-4": {
        "App": "app/",
        "GPBMetadata": "grpc/GPBMetadata",
        "Grpc": "grpc/Grpc"
    },
    "files": [
    ]
},

gRPC server 示例

server.php 文件(参考 配置):

'servers' => [
    ....
    [
        'name' => 'grpc',
        'type' => Server::SERVER_HTTP,
        'host' => '0.0.0.0',
        'port' => 9503,
        'sock_type' => SWOOLE_SOCK_TCP,
        'callbacks' => [
            SwooleEvent::ON_REQUEST => [HyperfGrpcServerServer::class, 'onRequest'],
        ],
    ],
],

routes.php 文件(参考 路由):

Router::addServer('grpc', function () {
    Router::addGroup('/grpc.hi', function () {
        Router::post('/sayHello', 'AppControllerHiController@sayHello');
    });
});

HiController.php 文件中的 sayHello 方法:

public function sayHello(HiUser $user) 
{
    $message = new HiReply();
    $message->setMessage("Hello World");
    $message->setUser($user);
    return $message;
}

.proto 文件中的定义和 gRPC server 路由的对应关系: /{package}.{service}/{rpc}

gRPC server 如何对 gRPC 请求进行处理的: HyperfGrpcServerCoreMiddleware::process() (vendor/hyperf/grpc-server/src/CoreMiddleware.php:46, 复制后直接使用 phpstorm 打开), 解析出 request_uri, 即得到 /{package}.{service}/{rpc} 信息, 然后调用好封装好的 gRPC 编解码类 HyperfGrpcParser::deserializeMessage(vendor/hyperf/grpc-server/src/CoreMiddleware.php:137), 就可以获取到请求的明文信息

gRPC server 如何进行 gRPC 响应, 相信你可以根据上面的信息, 自己发现.

gRPC client 示例

示例代码可以在 GrpcController 中找到:

public function hello()
{
    $client = new AppGrpcHiClient('127.0.0.1:9503', [
        'credentials' => null,
    ]);

    $request = new GrpcHiUser();
    $request->setName('hyperf');
    $request->setSex(1);

    /**
        * @var GrpcHiReply $reply
        */
    list($reply, $status) = $client->sayHello($request);

    $message = $reply->getMessage();
    $user = $reply->getUser();

    $client->close();
    var_dump(memory_get_usage(true));
    return $message;
}

hyperf 已经封装好了 HyperfGrpcClientBaseClient, 只要根据 .proto 文件中的定义, 按需扩展:

class HiClient extends BaseClient
{
    public function sayHello(HiUser $argument)
    {
        return $this->simpleRequest(
            '/grpc.hi/sayHello',
            $argument,
            [HiReply::class, 'decode']
        );
    }
}

写在后面

如果你是 gRPC 的重度使用者, 欢迎关注 hyperf 的后续开发者工具, 可以根据 .proto 文件生成全套 gRPC 代码.

原文地址:https://www.bookstack.cn/read/hyperf-1.1.20/grpc.md
文章来源与用户投稿或网络采集,如果您是本文的作者,发现版权或转载方式问题请右侧邮箱联系管理员。

抢沙发

我们不是孤独的个体,留下足迹,保持联系,成为团体...
姓名
电子邮件
个人主页