简体   繁体   English

使用 GRPC 流式传输多种类型的最佳方法

[英]Best approach to stream multiple types with GRPC

I have a server that passes messages to a client.我有一个将消息传递给客户端的服务器。 The messages are of different types and the server has a generic handleMessage and passMessage method for the clients.消息具有不同的类型,服务器具有用于客户端的通用handleMessagepassMessage方法。

Now I intend to adapt this and use GRPC for it.现在我打算对此进行调整并使用 GRPC。 I know I could expose all methods of the server by defining services in my .proto file.我知道我可以通过在我的.proto文件中定义服务来公开服务器的所有方法。 But is there also a way to:但是还有没有办法:

  • Stream
  • heterogenous types异质类型
  • with one RPC call一次 RPC 调用
  • using GRPC使用 GRPC

There is oneof which allows me to set a message that has only one of the properties set.oneof ,让我来设置只设置的属性之一的消息。 I could have a MessageContainer that is oneof and all my message types are included in this container.我可以有一个MessageContainer ,它是oneof并且我的所有消息类型都包含在这个容器中。 Now the container only has one of the types and I would only need to write one现在容器只有一种类型,我只需要写一种

service {
   rpc messageHandler(ClientInfo)  returns (stream MessageContainer)
}

This way, the server could stream multiple types to the client through one unique interface.这样,服务器可以通过一个独特的接口将多种类型流式传输到客户端。 Does this make sense?这有意义吗? Or is it better to have all methods exposed individually?还是单独公开所有方法更好?

UPDATE更新

I found this thread which argues oneof would be the way to go.我发现这个线程认为oneof是要走的路。 I'd like that obviously as it avoids me having to create potentially dozens of services and stubs.我显然希望如此,因为它避免了我必须创建潜在的数十个服务和存根。 It would also help to make sure it's a FIFO setup instead of multiplexing several streams and not being sure which message came first.这也有助于确保它是一个 FIFO 设置,而不是多路复用多个流并且不确定哪个消息先出现。 But it feels dirty for some reason.但是因为某种原因感觉很脏。

Yes, this makes sense (and what you are calling MessageContainer is best understood as a sum type ).是的,这是有道理的(您所说的MessageContainer最好理解为sum type )。

... but it is still better to define different methods when you can ("better" here means "more idiomatic, more readable by future maintainers of your system, and better able to be changed in the future when method semantics need to change"). ...但最好在可以的情况下定义不同的方法(“更好”这里的意思是“更惯用,系统的未来维护者更具可读性,并且在未来方法语义需要更改时能够更好地进行更改” )。

The question of whether to express your service as a single RPC method returning a sum type or as multiple RPC methods comes down to whether or not the particular addend type that will be used can be known at RPC invocation time.是否将您的服务表示为返回和类型的单个 RPC 方法或多个 RPC 方法的问题归结为在 RPC 调用时是否可以知道将使用的特定加数类型。 Is it the case that when you set request.my_type_determining_field to 5 that the stream transmitted by the server always consists of MessageContainer messages that have their oneof set to a MyFifthKindOfParticularMessage instance?难道,当你设置的情况下request.my_type_determining_field5由服务器传输的流总是由MessageContainer有他们的消息oneof集到MyFifthKindOfParticularMessage实例? If so then you should probably just write a separate RPC method that returns a stream of MyFifthKindOfParticularMessage messages.如果是这样,那么您可能应该编写一个单独的 RPC 方法来返回MyFifthKindOfParticularMessage消息流。 If, however, it is the case that at RPC invocation time you don't know with certainty what the used addend types of the messages transmitted from the server will be (and "messages with different addend types in the same stream" is a sub-use-case of this), then I don't think it's possible for your service to be factored into different RPCs and the right thing for you to do is have one RPC method that returns a stream of a sum type.但是,如果它是在RPC调用时你知道确切的使用加数类型从服务器传输的消息会是怎样的情况下(和“具有相同的流在不同加数类型的消息”是一个子-use-case of this),那么我认为您的服务不可能被分解到不同的 RPC 中,您应该做的正确的事情是拥有一个返回总和类型流的 RPC 方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM