How can I know which client's connection is lost on server side during stream connection?

378 views
Skip to first unread message

黄骐

unread,
Apr 25, 2017, 10:04:24 AM4/25/17
to grpc.io
Hi,
  I am working on some two way stream connection on grpc.
  This is how it work:
  When client make the first connect, I save the responseStreamObserver and link it with the client's user ID, 
  so the server can use the StreamObserver when needs to push message to client.
  But now I can not find a way to identify the client when connection is lost and "CANNCELED" is catched in onError on server side.

Is there any way to do this or is any problem with this kind of implementation of push function?

Thanks 

Eric Anderson

unread,
Apr 25, 2017, 12:39:51 PM4/25/17
to 黄骐, grpc.io
On Tue, Apr 25, 2017 at 7:04 AM, 黄骐 <sky7...@gmail.com> wrote:
  When client make the first connect, I save the responseStreamObserver and link it with the client's user ID, 
  so the server can use the StreamObserver when needs to push message to client.

That sounds good.

  But now I can not find a way to identify the client when connection is lost and "CANNCELED" is catched in onError on server side.

If the client has already completed its side of the stream, then onError won't be called, because it can only be called once. Instead, You can call ServerCallStreamObserver.setOnCancelHandler(Runnable) and the Runnable will be executed if the client disconnects. To get the ServerCallStreamObserver, simply cast the request StreamObserver.

An alternative is to use Context.addListener(CancellationListener, Executor) as the Context is also cancelled when the RPC is cancelled (all I/O failures on server-side act like cancellation in the API).

黄骐

unread,
Apr 26, 2017, 10:16:58 AM4/26/17
to grpc.io, sky7...@gmail.com
Thanks for the reply. I try ServerCallStreamObserver and Context, and find out that they solve half of my problem: to get a callback when cancellation.
Then the other half is just I was confused by myself. 

So I just list all the staff here in case someone may need

public StreamObserver<Message> chat(StreamObserver<Message> responseObserver){

   
final UserData data = new UserData();
   
   
final ServerCallStreamObserver<Message> rsob = (ServerCallStreamObserver<Message>) responseObserver;
   rsob
.setOnCancelHandler(new Runnable() {
     
@Override
      public void run() {
         
System.out.println("OnCancelHandler:" + data.name);//
      }
   
});
   
   
return new StreamObserver<Message>() {
     
@Override
      public void onNext(Message value) {
         
data.name = value.getFrom();
     
}

UserData is a POJO.
chat() will be call when client begin RPC, so just create UserData there and use it in onError and other callbacks. 




在 2017年4月26日星期三 UTC+8上午12:39:51,Eric Anderson写道:
Reply all
Reply to author
Forward
0 new messages