我是 gRPC 的新生,这是我的问题。我正在尝试编写一个服务,以根据以下服务方法将 myOwnService
公开到 gRPC 服务中:
rpc HighFive (stream HighRequest) returns (stream HighReply) {}
服务端代码如下:
func (s *server) HighFive(stream pb.Greeter_HighFiveServer) error {
// Oops, don't know how to do here ...
myOwnService(stdin io.ReadCloser, stdout io.WriteCloser)
return nil
}
func myOwnService(stdin io.ReadCloser, stdout io.WriteCloser) error {
// read input from stdin, do something, the write result to stdout
...
return nil
}
正如你在上面看到的,我不知道如何让 stream
在我的原始文件中与 io.Reader
和 io.Writer
一起工作服务,这样HighFive
gRPC服务的调用者就可以像正常调用myOwnService
一样读写数据。
[更新]我目前的消息是这样的,但如果需要你可以改变它们:
message HighRequest {
bytes content = 1;
}
message HighReply {
bytes content = 1;
}
最佳答案
根据 the gRPC Basics tutorial section on Bidirectional streaming RPC ,每次调用您的 stream
参数的 Recv
方法都会给您解码的 HighRequest
消息,不是字节流,正如您对 myOwnService
函数所期望的那样。
现在,如果您的 HighRequest
消息包含一个类型为 bytes
或 string
的字段,您可能希望将该字段的内容提供给 myOwnService
作为 stdin
参数,通过 bytes.NewReader
包装原始 []byte
值.
不过,我看到 myOwnService
需要一个 io.ReadCloser
。我不知道为什么您会期望 myOwnService
关闭其输入参数,但我会非常信任您,您需要它然后推荐使用 ioutil.NopCloser
轻松满足该需求。
素描:
// Next tag: 2
message HighRequest {
bytes content = 1;
}
func (s *server) HighFive(stream pb.Greeter_HighFiveServer) error {
for req, err := stream.Recv(); {
if err != nil {
if err == io.EOF {
return nil
}
return err
}
in := ioutil.NopCloser(bytes.NewReader(req.Content))
out := /* ... */
if err := myOwnService(in, out); err != nil {
return err
}
}
}
关于go - 如何使 Go gRPC 在服务器端与标准 IO 一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37240385/