Some comments / questions:

1.  Why doesn't "rpc register" get split into two methods, one per type?  
Like "rpc registerCee (CeeRegRequest) returns (CeeRegResponse);"

2.  Being careful with terminology, you have multiple "services" on a singe 
"server", and the "server" is at one address.   

3.  You can find all services, methods, and types using the reflection api, 
typically by adding ProtoReflectionService to your Server.  

4.  BindableService and ServerServiceDefinition are standard and stable 
API, you can make them if you want.  The Protobuf generated code makes its 
own (and is complicated for other reasons) but you can safely and easily 
construct one that you prefer.

5.  Multiple ports is usually for something special, like different socket 
options per port, or different security levels.  That is a more advanced 
feature less related to API. 

On Wednesday, February 13, 2019 at 10:58:51 AM UTC-8, Geoff Groos wrote:
>
> Hey everyone
>
> I'm building an API with GRPC which currently looks like this:
>
> serivce OurEndpoint {
>    rpc register (RegistrationForFeatureCeeAndDee) returns (stream 
> FeatureCeeOrDeeRequest) {}
>      
>    rpc featureA (FeatureAyeRequest) returns (FeatureAyeReponse) {}
>    rpc featureB (FeatureBeeRequest) returns (FeatureBeeResponse) {}
>    
>    rpc offerFeatureC(FeatureCeeResponse) returns (Confirmation) {}
>    rpc offerFeatureD(FeatureDeeResponse) returns (Confirmation) {}
>    rpc offerCeeOrDeeFailed(FailureResponse) returns (Confirmation) {}
> }
>
>
> message FeatureCeeOrDeeRequest {
>     oneof request {
>         FeatureDeeRequest deeRequest = 1;
>         FeatureCeeRequest ceeRequest = 2;      
>     }
> }
>
>
> message Confirmation {}
>
> Note that features A and B are fairly traditional client-driven 
> request-response pairs.
>
> Features C and D are callbacks; the client registers with
>
> I can provide answers to C and D, send me a message and I'll call 
> offerFeatureResponse 
>> as appropriate.
>
>
> I don't like this. It makes our application code complex. We effectively 
> have to build our own multiplexer for things like offerCeeOrDeeFailed
>
> What I'd really rather do is this:
>
> serivce OurEndpoint {
>    rpc register (RegistrationForFeatureCeeAndDee) returns (Confirmation) 
> {}
>      
>    rpc featureA (FeatureAyeRequest) returns (FeatureAyeReponse) {}
>    rpc featureB (FeatureBeeRequest) returns (FeatureBeeResponse) {}  
> }
> service EndpointClientMustImplement {
>    rpc featureC(FeatureCeeRequest) returns (FeatureCeeResponse) {}
>    rpc featureD(FeatureDeeRequest) returns (FeatureDeeResponse) {}
> }
>
>
> message RegistrationForFeatureCeeAndDee {
>    ConnectionToken name = 1;
> }
>
>
> message Confirmation {}
>
>
> The problem here is how to go about implementing ConnectionToken and its 
> handler. Ideally I'd like some code like this:
>
> //kotlin, which is on the jvm.
> override fun register(request: RegistrationForFeatureCeeAndDee, response: 
> ResponseObserver<Confirmation>) {
>    
>     //...
>    
>     val channel: Channel = ManagedChannelBuilder
>             .for("localhost", 5551) // a port shared by the service 
> handling this very response
>             .build()
>            
>     val stub: EndpointClientMustImplement = EndpointClientMustImplement.
> newBuilder()
>             .withServiceNameOrSimilar(request.name)
>             .build()
>            
>     //....
> }
>
> What is the best way to go about this?
> 1. Can I have multiple servers at a single address?
> 2. Whats the best way to find a service instance by name at runtime rather 
> than by a type-derived (and thus by statically bound) name? I suspect the 
> BindableService and ServerServiceDefinitions will help me here, but I 
> really don't want to mess with the method-table building and the code 
> generating system seems opaque. 
>
> I guess my idea solution would be to ask the code generator to generate 
> code that is open on its service name, --ideally open on a constructor 
> param such that there is no way to instance the service without specifying 
> its service name.
>
> Or, perhalps there's some other strategy I should be using? I could of 
> course specify port numbers and then instance grpc services once-per-port, 
> but that means I'm bounded on the number of ports I'm using by the number 
> of active API users I have, which is very strange.
>
> Many thanks!
>
> -Geoff
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/81261a66-6f7a-47f2-9532-fceb1191e239%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to