It seems you are using C# server and the entire gRPC C# logic is implemented around the "async-await" pattern, which means there are no threads being
consumed if you await events in the right way (it's a bit more nuanced, but in short you should never use a blocking wait, but rely on the await keyword - I recommend reading up a bit on how async await works and the best practices).
On the client side, the API for streaming calls is also fully asynchronous - that means if you are reading from the responseStream (await responseStream.MoveNext()),
no thread is being consumed (the async method just yields the thread and revives when there is something to consume). This is true unless you add some blocking
primitives in your code yourself.
So basically, the solution would look something like this (there's many ways, this is just one of them):
- server keeps a pool of active subscribers.
- whenever an event is to be pushed to clients, send it to all subscribers using WriteAsync(), that can be done in parallel without blocking
- clients wait for events in an async loop (which calls await responseStream.MoveNext()), but as this is purely async, there are no "blocking" threads.
- if the RPC is interrupted, client connects to the server again.
No changes are needed on gRPC side.