来自google.golang.org/grpcUnaryClientInterceptor接口具有如下签名

type UnaryClientInterceptor func(ctx context.Context, method string, req, reply any, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error

我对该接口的理解是,实现是在请求发出之前调用的,允许在请求到达网络之前对其进行丰富和修改.

然而,我不理解reply参数,因为请求还没有发出.我是不是误解了这个接口的用法,或者即使在我们无法实际访问响应的情况下,使用reply参数也可以做一些有趣的事情吗?

推荐答案

在进行GRPC调用之后,您可以判断reply参数内的响应.

一元拦截器的参数之一是invoker函数,它的类型为UnaryInvoker.在一元拦截器中,您应该调用此函数,如文档中所述:

调用器是完成RPC的处理程序,拦截器负责调用它

invoker本身就把reqreply作为自变量.您可以调用调用器and then判断reply.

But, how to inspect it?接口reply的动态类型应该是指向您的ProtoBuffer模式中定义的GRPC处理程序的返回类型的指针.您可以判断method的值,以了解预期的返回类型.

为了更好地理解这一点,您可以查看一下由protoc生成的代码.GRPC方法的实现显示了用于调用Invoke的实际参数是什么.

假设您有一个协议缓冲区,如下所示:

package foo;

service MyService {
    rpc GetFoo(FooRequest) returns (FooResponse);
}

GetFoo方法生成的代码如下所示:

func (c *myServiceClient) GetFoo(ctx context.Context, in *FooRequest, opts ...grpc.CallOption) (*FooResponse, error) {
    out := new(FooResponse)
    err := c.cc.Invoke(ctx, "/foo.MyService/GetFoo", in, out, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}

因此,您可以根据值method知道reply的类型.然后,您可以获得以下示例一元拦截器:

grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
    // some interceptor logic
    // ...
    // then you must call invoker
    err := invoker(ctx, method, req, reply, cc, opts...)
    if err != nil {
        // handle error
    }
    // finally you can inspect reply before returning
    switch method {
    case "/foo.MyService/GetFoo":
        fooResp := reply.(*FooResponse)
        // access fields to do whatever you want

    // other switch cases as needed
    }
    return nil
}),

Go相关问答推荐

如何将泛型函数作为参数传递给golang中的另一个函数?

如何复制*C.char?

Websocket服务器实现与x/net库trowing 403

如何在Golang中使用ECHO服务器实现Socket.IO服务器

将DATE类型的SQL字段扫描到GO struct 字段

golang regex基于关键字拆分字符串

如何模拟 stripe 需要 webhooks 的捕获事件?

未实现的 desc = 未知服务 pb.AuthService 我的简单身份验证服务器上出现错误

Go Gin:验证 base64

Go 中如何判断 struct 体是否包含另一个 struct 体?

仅使用公共 api 对 alexedwards/scs 进行简单测试

在两个单独的速率受限端点之间同步请求

设置指向空接口的指针

如何在切片增长时自动将切片的新元素添加到函数参数

GRPC 元数据未在 Go 中更新

Go AST:获取所有 struct

如何使路径/不匹配 Golang net/http 中所有其他不匹配的路径

从 map 返回空数组而不是空字符串数组

如何迭代在泛型函数中传递的片的并集?

更改单个像素的 colored颜色 - Golang 图像