I'm wondering if it's a good idea to push data from gRPC server to a client. Basically I want to use a pub/sub pattern with gRPC. The way I do is that I return a response stream on the server implementation that I never close. Then, the client has a never ending go routine in charge of reading this stream.
Here is an example:
service Service {
rpc RegularChanges (Void) returns (stream Change) {}
}
On the server side:
func (self *MyServiceImpl) RegularChanges(in *pb.Void, stream pb.Service_RegularChangesServer) error {
for {
d, err := time.ParseDuration("1s")
if err != nil {
log.Fatalf("Cannot parse duration")
break;
}
time.Sleep(d)
stream.Send(&pb.Change{Name:"toto", Description:"status changed"})
}
return nil
}
On client:
for {
change, err := streamChanges.Recv()
if err != nil {
log.Fatalf("Error retrieving change")
} else {
log.Println(change)
}
}
I just began with go and gRPC but I know it's based on HTTP2, hence it should support pushing datas. However, I'm not sure this is the way gRPC should be used.
gRPC is intended to be used in this way.
You should still consider how the client should behave on failures and how you may want to re-balance across backends. If your connection is going across the Internet, you may also want to enable keepalive to detect connection breakages by providing KeepaliveParams to the client and server.