转到 gRPC 流范围

标签 go grpc

TLDR;如果我的 Go gRPC 双向流服务器在 Recv/Send 上无限循环,当我的客户端的 stream 掉线时如何关闭连接作用域并获得 GC?


假设我正在使用 Go 进行 gRPC 双向流式调用:

syntax = "proto3";

package mystical;

service Unicorn {
    rpc RainbowStream(stream Rainbow) returns (stream Rainbow);
}

我有一个服务器实现,我将在我的 gRPC 服务器上注册:

type Server struct {}

func (serv *Server) RainbowStream(stream proto.Unicorn_RainbowStreamServer) error {
    // Stub implementation
    // Just sends the rainbows back
    for {
        msg, err := stream.Recv()
        if err != nil {
            return err
        }
        if err := stream.Send(msg); err != nil {
            return err
        }
    }
}

然后我有一个客户端,省略了一些 gRPC 细节:

type Client struct {
    proto.UnicornClient
}

func (c *Client) TastyColors() (stream proto.Unicorn_RainbowStreamClient, err error) {
    return c.RainbowStream()
}

我这样做:

func somewhereDeepInMyCode() {

    stream, err := aClient.TastyColors()
    // ...

    go func() {
       stream.Send(msg)
       // ...
       // eventually this goroutine ends
       // and `stream` would get GC'd
    }
}

stream 超出范围时,gRPC 流调用会自行清理吗?通常,据我了解,服务器必须返回其 RainbowStream 调用以关闭连接。如果它不自行清理,我该如何实现?

最佳答案

使用取消(https://golang.org/pkg/context/#WithCancel)上下文从客户端取消:

func somewhereDeepInMyCode() {
    ctx, cancel := context.WithCancel(context.Background())
    stream, err := aClient.TastyColors(ctx)
    // ...

    go func() {
        defer cancel()
        stream.Send(msg)
        // ...
        // eventually this goroutine ends
        // and `stream` would get GC'd
    }
}

服务器可以根据需要处理客户端取消以进行清理:

for {
    select {
    ...
    case <-stream.Context().Done():
    // cleanup
    ...
    }
}

关于转到 gRPC 流范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50780559/

相关文章:

c - 如何在 GO 中将 "_Ctype_int"更改为 "int"?

go - 如何在 Go 中获取系统信息?

go - go grpc-go健康检查如何实现?

java - gRPC 服务器可以在另一个 HTTP/2 网络服务器(如 jetty/undertow/tomcat)之上运行吗?

c++ - gRPC KeepAlive/空闲超时

struct - Golang 将函数添加到别处定义的结构

datetime - 如何在golang中将RFC3339格式转换为ISO8601?

pointers - Go指向不同存储位置但更新相同变量的指针

node.js - 你如何在 TypeScript 中实现 GRPC 服务器?

java - GRPC Java 将数据从服务器拦截器传递给 rpc 服务调用