简体   繁体   中英

In gRPC c++, is there a way to get notified when the peer gets disconnected?

I have implemented a gRPC server application and multiple clients can connect to it and call RPCs. In the cases of client disconnection or client restarts, I would want to know which client got disconnected so that I can do some cleanup corresponding to that client.

Similarly, if the server goes down, how can the client get notified?

Does gRPC c++ stack provides a notification/callback to the application? If not, what is the best way to handle the connection termination on either side?

Tcp is an idle protocol so in order to detect dropped connection you will have to implement some type of ping/pong and timers to throw broken connections so you should do something like this:

in one side (eg client):

  • you have a timer which waits for some time (like 1 minute)
  • each write to the server rests the timer
  • when receiving a packet you update the last time you received a packet
  • when the timer expires you check if the ping time was reached (you didn't send anything for a minute) then if so send a ping message, and the server should reply. if the connection is broken you are likely to get an error on send.
  • after checking the ping time, check the last time you received a packet and if it exceeds the chosen session timeout (should be longer than ping timeout) then the server failed to respond to your message, pings so drop the connection

in the other side (eg server):

  • you have a timer which waits for the session timeout
  • each write to the client rests the timer
  • when receiving a packet you update the last time you received the packet
  • once you get a ping send a pong message to inform the client you are still connected
  • when the timer has expired check the last time you received a packet and if it exceeds the session timeout then the client failed to ping the server or send any message so assume the client has disconnected and drop the connection

in side with this, any error from read, write (other than non blocking errors and likes) are treated as disconnection.

Note that ping and pong is important because you may send only other messages when required (when some work is done) which may take long time so during this time you should ping the server to check if it is still in connection with you

gRPC tries to abstract away details of connection management away from the user so some of these details are intentionally hidden. This means that gRPC servers see incoming RPCs rather than clients, (though you would be able to call peer() on the ServerContext to get the client's uri). At the RPC level, you would be able call IsCancelled() on the ServerContext to check whether the RPC failed for some reason (a disconnect would count as a failure).

For the client, again the connection details are abstracted away. On each new RPC, if the channel is not already connected, a new connection attempt would made. This way disconnects are not really visible to the user unless the disconnect happened while an RPC was ongoing in which case the status details would point to a disconnect. Note that gRPC does provide the NotifyOnStateChange() API on the channel so as to get notified on any state changes on the broader channel. If the application guarantees that the channel uses a single server, then NotifyOnStateChange() can be used to check when the transports disconnects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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