8

我有一个 GRPC 服务器,它提供一个函数并返回一个流。我想将流保存到一个map[string]grpc.Stream- 这到目前为止有效。

我的问题是在返回流的函数完成其逻辑后流被关闭。

这就是我到目前为止所拥有的:

func (s *server) CheckConnection(initMessage *LighterGRPC.InitMessage, stream LighterGRPC.Lighter_CheckConnectionServer) error {
    //Do something magic
    streams[initMessage.DeviceID] = stream

    error := stream.Send(&LighterGRPC.ColorMessage{DATA})
    if error {
        log.Println(error)
    }

    //Tried
    //for { }

    return error
}

我已经尝试让函数在返回之前永远不要返回任何带有 a 的东西for {}(如上面代码中所述),但这没有帮助,我不认为这可能是解决方案。

有没有办法让流保持打开状态,以便稍后在运行时通过它向客户端发送数据?

4

1 回答 1

1

对于那些可能遇到同样问题的人,这里是快速解决方案。基本上,您需要将您的流包装在一个结构中,以便有一个错误chan。Return 将阻塞,直到执行 stream.Send() 时发生错误

type Connection struct {
    stream LighterGRPC.Lighter_CheckConnectionServer
    error  chan error
}

你的地图会像:

type Server struct {
    ....
    conns map[string]Connection
}

最后创建流的 RPC 应该是这样的:

conn := Connection{
    stream: stream,
    error:  make(chan error),
}
s.conns[initMessage.DeviceID] = conn

return <-conn.error

这样,您的流将在“活动”时存储在地图中。

于 2020-06-08T06:29:14.413 回答