spiral/grpc-client

gRPC客户端

1.0.0-alpha3 2024-08-02 13:31 UTC

This package is auto-updated.

Last update: 2024-09-02 20:56:23 UTC


README

该包提供了一种通过简单和可扩展的接口进行客户端gRPC请求的强大和方便的功能。

安装

composer require spiral/grpc-client -W

PHP Latest Version on Packagist License Total downloads

请注意,该包需要安装gRPC扩展

文档

公共API

该包提供了API的以下部分

  • 用于框架的集成类。
  • 通过DTO方便配置包的类。
  • 一组基本的拦截器
  • 几种类型的异常用于错误处理。

集成

Spiral

注意

从版本4.0.0开始,spiral/roadrunner-bridge包默认包含spiral/grpc-client包,并提供了其集成和配置流程。

\Spiral\Grpc\Client\Bridge\GrpcClientBootloader引导加载器添加到应用程序配置中的引导加载器列表中(通常是Kernel.php)。

其他框架

如果您在使用此包时不在Spiral框架内,您需要找出如何使用\Spiral\Grpc\Client\ServiceClientProvider提供者来获取可用的gRPC客户端。

配置DTOs

现在让我们考虑一个配置示例

use Spiral\Grpc\Client\Config\GrpcClientConfig;
use Spiral\Grpc\Client\Config\ServiceConfig;
use Spiral\Grpc\Client\Config\ConnectionConfig;
use Spiral\Grpc\Client\Interceptor\SetTimoutInterceptor;
use Spiral\Grpc\Client\Interceptor\RetryInterceptor;
use Spiral\Grpc\Client\Interceptor\ExecuteServiceInterceptors;

new GrpcClientConfig(
    interceptors: [
        SetTimoutInterceptor::createConfig(10_000), // 10 seconds
        RetryInterceptor::createConfig(
            maximumAttempts: 3,
            initialInterval: 100, // 0.1 seconds
            backoffCoefficient: 1.5,
        ),
        ExecuteServiceInterceptors::class,
    ],
    services: [
        new ServiceConfig(
            connections: ConnectionConfig::createInsecure('my-service:9001'),
            interfaces: [
                \GRPC\MyService\MailSenderInterface::class,
                \GRPC\MyService\BlackListInterface::class,
                \GRPC\MyService\SubscriberInterface::class,
            ],
        ),
    ],
)

GrpcClientConfig

此类表示gRPC客户端的一般配置。它包括服务配置列表和将应用于所有服务的一般拦截器列表。

拦截器可以声明为类名、Spiral\Core\Container\Autowire对象(如果需要传递自定义构造函数参数)或对象。请注意,某些拦截器提供了创建配置的方便方法。

ServiceConfig

此类表示特定服务或具有不同连接选项的类似服务的配置。

interfaces参数是由protoc工具生成的gRPC服务接口列表,这些接口由服务实现。

注意

目前,我们仅支持使用protoc工具和protoc-gen-php-grpc插件生成的服务接口。

上述配置示例中没有包含interceptors参数。它与一般配置相同,但仅应用于指定的服务。此拦截器分支通过ExecuteServiceInterceptors拦截器运行。因此,如果您想使用特定于服务的拦截器,则非常重要。

connections参数是连接配置列表。您可以指定多个连接以在它们之间分配负载或提供故障转移。可以通过拦截器配置多连接编排策略,例如,ConnectionsRotationInterceptor

ConnectionConfig

此类表示与gRPC服务的单个连接的配置。它包括凭证和服务地址。使用静态方法创建具有不同类型凭证的连接配置。

用法

集成和配置就绪后,您可以从容器中获取所需服务接口的客户端并调用服务方法。

final class Sender
{
    public function __construct(
        private \GRPC\MyService\MailSenderInterface $mailSender,
    ) {}

    public function sendMail(string $email, $subject, string $message): bool
    {
        $request = (new \GRPC\MyService\SendMailRequest())
            ->setEmail($email)
            ->setSubject($subject)
            ->setMessage($message);

        $response = $this->mailSender->sendMail(new \Spiral\RoadRunner\GRPC\Context([]), $request);
        return $response->getSuccess();
    }
}

拦截器

长时间运行模式下使用拦截器的要点

  • 有状态的:对于每个请求都会重新创建拦截器,因此您可以安全地存储每个调用的状态。
  • 作用域:拦截器在调用客户端的相同容器作用域中创建。相应地,您可以在拦截器的构造函数中请求上下文依赖项。

在编写自己的拦截器时,您可能需要与gRPC特定的字段(选项、元数据、输入消息等)进行交互。使用\Spiral\Grpc\Client\Interceptor\Helper类来获取或设置这些上下文字段的值。

final class AuthContextInterceptor implements InterceptorInterface
{
    public function __construct(
        private readonly AuthContextInterface $authContext,
    ) {}

    public function intercept(CallContextInterface $context, HandlerInterface $handler): mixed
    {
        $token = $this->authContext->getToken();

        if ($token === null) {
            return $handler->handle($context);
        }

        $metadata = \Spiral\Grpc\Client\Interceptor\Helper::withMetadata($context);
        $metadata['auth-token'] = [$token];

        return $handler->handle(\Spiral\Grpc\Client\Interceptor\Helper::withMetadata($context, $metadata));
    }
}

拦截器的顺序

拦截器按照在配置中声明的顺序执行。拦截器的顺序很重要。

例如,如果我们有以下配置

  1. 设置超时(10秒)
  2. 重试(最大尝试次数:3,间隔:2秒)
  3. 设置超时(3秒)

那么,我们将为每个重试尝试设置3秒的超时时间。
我们还为所有尝试设置了10秒的超时时间,在此之后将不会进行新的请求尝试。这是因为RetryInterceptor考虑了之前配置的超时时间。

此外,ExecuteServiceInterceptors拦截器的放置,它包含当前运行服务的拦截器,将影响最终的拦截器顺序。