How can I detect when a client disconnects?

77 views
Skip to first unread message

Joe Ludwig

unread,
May 12, 2019, 2:52:49 PM5/12/19
to Cap'n Proto
I'm using EzRpcServer and EzRpcClient, and I'd like to do some cleanup on the server when a client disconnects. 

Inside the implementation of EzRpcServer I see that it's getting a promise when accepting a new client that appears to do some work on client disconnect: That calls onDisconnect on the TwoPartyVatNetwork in the EZ server's implementation:
      // Arrange to destroy the server context when all references are gone, or when the
     
// EzRpcServer is destroyed (which will destroy the TaskSet).
      tasks
.add(server->network.onDisconnect().attach(kj::mv(server)));


Is there any way to get this same promise through the EzRpcServer object itself? Or some other way to know when a client has disconnected?


Joe

Kenton Varda

unread,
May 12, 2019, 4:43:28 PM5/12/19
to Joe Ludwig, Cap'n Proto
Hi Joe,

I recommend using the TwoPartyServer class, rather than EzRpcServer. The "EZ" classes are really only meant for the simplest of use cases; if you find you need to do something they don't support, then it's time to move on to the lower-level APIs.

-Kenton

--
You received this message because you are subscribed to the Google Groups "Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+...@googlegroups.com.
Visit this group at https://groups.google.com/group/capnproto.
To view this discussion on the web visit https://groups.google.com/d/msgid/capnproto/cd411d8f-4be8-405b-85bc-9b174133a879%40googlegroups.com.

Joe Ludwig

unread,
Jun 22, 2019, 8:23:58 PM6/22/19
to Cap'n Proto
Ok, I've zoomed in a little and how have the implementation of EzRpcServer (and client) in my app so I can get at their innards. 

I can see in the acceptLoop function where onDisconnected is called, and if I run some code when that promise is resolved I can go clean things up. But when I went to do that I realized I didn't know what to clean up.

When implementing an RPC call you get a signature like this:
::kj::Promise<void> createApp( CreateAppContext context )

(Where createApp is the name of the RPC call.) 

That function is on the server implementation class for the main interface. In my case that's a class called AvServerImpl. There's one of those for the whole server and each client gets a capability that lets it make calls on that single server object. Or at least that's how it's working for me now.

I can't see anything in CreateAppContext that lets me know which client is actually making the call. And there's only one AvServerImpl, so that doesn't help either. I've read your coding standard, so I think it's unlikely that there's some global somewhere with a this bit of context stored in it. :)

So how do I associate a request with a specific client? Do I need to cause there to be multiple AvServerImpl objects somehow and then thunk over to the shared-across-all-clients implementation with this extra context attached? It looks like to do that I'd need one restorer per client since that seems to be what actually returns the main interface.


Joe

On Sunday, May 12, 2019 at 1:43:28 PM UTC-7, Kenton Varda wrote:
Hi Joe,

I recommend using the TwoPartyServer class, rather than EzRpcServer. The "EZ" classes are really only meant for the simplest of use cases; if you find you need to do something they don't support, then it's time to move on to the lower-level APIs.

-Kenton

On Sun, May 12, 2019 at 11:52 AM Joe Ludwig <progra...@gmail.com> wrote:
I'm using EzRpcServer and EzRpcClient, and I'd like to do some cleanup on the server when a client disconnects. 

Inside the implementation of EzRpcServer I see that it's getting a promise when accepting a new client that appears to do some work on client disconnect: That calls onDisconnect on the TwoPartyVatNetwork in the EZ server's implementation:
      // Arrange to destroy the server context when all references are gone, or when the
     
// EzRpcServer is destroyed (which will destroy the TaskSet).
      tasks
.add(server->network.onDisconnect().attach(kj::mv(server)));


Is there any way to get this same promise through the EzRpcServer object itself? Or some other way to know when a client has disconnected?


Joe

--
You received this message because you are subscribed to the Google Groups "Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capn...@googlegroups.com.

Kenton Varda

unread,
Jun 23, 2019, 2:05:24 AM6/23/19
to Joe Ludwig, Cap'n Proto
Hi Joe,

RpcSystem has an alternative constructor which lets you provide a factory function to generate a new bootstrap capability (i.e. the main interface) for each connection:


Maybe that helps?

-Kenton

To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+...@googlegroups.com.

Joe Ludwig

unread,
Jun 23, 2019, 12:40:25 PM6/23/19
to Cap'n Proto
Hi Kenton,

That definitely helps with creating one capability per connection. And now that I have a unique server object per connection, I can assign IDs to those and know what to clean up.

Thanks!


Joe




On Saturday, June 22, 2019 at 11:05:24 PM UTC-7, Kenton Varda wrote:
Hi Joe,

RpcSystem has an alternative constructor which lets you provide a factory function to generate a new bootstrap capability (i.e. the main interface) for each connection:


Maybe that helps?

-Kenton
Reply all
Reply to author
Forward
0 new messages