I'm creating a bidirectional stream for sending messages from a gRPC server to its client. The server is created using:
...
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(this);
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
server->Wait();
...
Here is an excerpt from the service definition .proto file:
...
rpc OpenCallBackChannel(stream CallBackAPIResponseMessageToServer) returns (stream CallBackAPIRequestMessageFromServer) {}
...
The client calls the server's method OpenCallBackChannel
to start a bidirectional communications session. In the server-side handler for this method I save the context and stream passed to this handler, say _context
& _stream
, respectively.
I send messages to client using _stream.Write
, and read response messages from client using _stream.Read
.
Using _context->IsCancelled()
I can check if the channel has been dropped before I try to read from it using _stream.Read
.
Is there a method to know when the bidirectional channel is no longer valid without having to call _context->IsCancelled()
periodically?
BR
As I was using the synchronous API, at the end I created a worker thread and passed the stream. According to grpc's documentation writing/reading is thread-safe for this stream.
When clients close/cancel the channel,
_stream.Read()
fails, and_context->IsCancelled()
returns true. That's the moment for ending the stream reading thread and to notify the rest of the application of this event.I pass read messages to a received-messages queue, read them from where I need them, with a read timeout which is something I needed too.
Maybe not the neatest solution, surely not compared to the async API, but it works.