RTC Forums

Subscription => Support => Topic started by: colutti on September 24, 2010, 08:20:40 PM



Title: OnDisconnect
Post by: colutti on September 24, 2010, 08:20:40 PM
Hello guys

I am developing a webserver. This webserver will receive a client request that can take a lot to complete at server side. But, it may happens that the client gets disconnected, even because the user closed the client app or the client app reached its timeout. If that happens, my webserver will keep doing its working. I need an way of canceling this work when the client gets disconnected.
I was thinking about using OnClientDisconnect to know that a client disconnected and stop doing its work. But I need a way to unique identify the client. Maybe using sessions and storing the session at Request.Info property, but i have no clue of how to do that.
I so have no ideia of how to use Request.Info property .....
Can anybody help me?

P.S: sorry for my bad english. I am brazilian.


Title: Re: OnDisconnect
Post by: D.Tkalcec (RTC) on September 24, 2010, 08:42:35 PM
If your Server is supposed to execute very long requests, I think you should re-think your strategy and implement the communication between the Server and the Client independent of the physical connection status during Server processing time, or you could easily get into situations where your clients connections will be forcibly closed by Proxy servers thinking the Server has become unstable if there is no response for X seconds (X is usually 30, but could be shorter or longer depending on the Proxy in use).

Also please note that the Request object only exists for the duration of a request/response loop. This means that you won't have access to the Request object from the OnDisconnect event. What you would have access to is the "TRtcDataServer(Sender).Info" property, which is linked to the physical connection and will be available in all events - from the point where a new connection is created to the point where a connection is closed. If you need to store some user-specific data for use between connection-specific events, you have to place it there.

Best Regards,
Danijel Tkalcec


Title: Re: OnDisconnect
Post by: colutti on September 24, 2010, 08:59:07 PM
It should be ideal, but i really need to do that.
Is the session available in the OnDisconnect event?
Do you have an example of using the Request.Info property? I was not abe to understand it. I need to store a string and read it back.


Title: Re: OnDisconnect
Post by: D.Tkalcec (RTC) on September 24, 2010, 09:11:00 PM
Provided you use the OnDisconnect event on the TRtcDataProvider component where the Request object still exists, you can use the "TRtcDataServer(Sender).Request.Info" property like this:

with TRtcDataServer(Sender).Request.Info do
  begin
  asString['myfield1']:=myfield1value;
  asString['myfield2']:=myfield2value;
  asInteger['myfield3']:=myfield3value;
  end;

To read the data, simply turn things around like ...

with TRtcDataServer(Sender).Request.Info do
  begin
  myfield1value := asString['myfield1'];
  myfield2value := asString['myfield2'];
  myfield3value := asInteger['myfield3'];
  end;

PS. You can access the Session from the OnDisconnect event, but to do that you need to use the FindSession method to lock it.

Best Regards,
Danijel Tkalcec


Title: Re: OnDisconnect
Post by: colutti on September 24, 2010, 10:06:29 PM
Ok .. perfect. It worked like a charm.
But .. how much time the server waits to call the ondisconnect event when the client is gone?
I sent a request to the server and i closed the client app. The server took to much time to realize that the client was gone ....


Title: Re: OnDisconnect
Post by: D.Tkalcec (RTC) on September 24, 2010, 10:21:07 PM
Provided the "Blocking" property of the TRtcHttpServer component is FALSE so the RTC SDK uses Async WinSock, and provided the connection thread is NOT currently blocked by an event being executed, the RTC SDK will trigger the disconnect event immediately if it gets a "FD_CLOSE" message from WinSock (meaning that the connection has closed). But ... how long it will take for WinSock to notice that a connection is not longer active depends on a lot of factors which the RTC SDK has no control over.

Best Regards,
Danijel Tkalcec


Title: Re: OnDisconnect
Post by: colutti on September 24, 2010, 11:02:09 PM
OK... but what happens if RTC did not receive de "Fd_Close" message from the client? How long it will wait until it fires de event?


Title: Re: OnDisconnect
Post by: colutti on September 24, 2010, 11:07:32 PM
Btw .. i am using TRtcDataProvider OnDisconnect event.


Title: Re: OnDisconnect
Post by: D.Tkalcec (RTC) on September 24, 2010, 11:22:53 PM
If there are no messages received from WinSock and you do not explicitly set Timeout values to force a disconnect if a connection is idle for X seconds (which you can do by using the "TimeoutsOfAPI" and "Timeouts" properties), the connection could theoretically stay open infinitely.

If you want a connection to be forcibly closed when there is no data being sent nor received through it for some time, use the Timeouts property. But if you do so, make sure your timeout values aren't too short because using a too short timeout period will force your connections to close when the Server is processing data (because of which there is currently no traffic) even if the connection is actually active.

Btw ...
1) What is the physical distance between your Client and your Server? Are they connected over the Internet?
2) Is it possible that there is a Proxy between the Client and the Server and the connection you are receiving at the Server actually came from the Proxy?
3) How did you close the connection on the Client side (terminated the Client or closed the Client app nromally or plugged the cable out) and how long did it take for the Server to receive the OnDisconnect event?

Best Regards,
Danijel Tkalcec


Title: Re: OnDisconnect
Post by: colutti on September 26, 2010, 11:17:26 PM
I guess what i need is Timeout and ApiTimeOut properties.
I created both server and client, so i have full control over them. But sometimes the client timeout is too short and my server keeps working even if the client timed out. What i will do is an way of sendind the timeout property of the client to my server. This way, my server will know how much time the client will wait for an response. I will set the clients timeout in those propertys (timeout and apitimeout) and the service will know when the client is gone. Is there a specific TimeOut and ApiTimeout that works for each connection instead of all connections?
But... I also need i way to identify that the connection on the client side got terminated (when, for example, an user plugged the cable out) so i can cancel the server work very fast, becase theres no client to send the response to anymore.
What specifically property should I use (there are many in TimeOut and ApiTimeout)?

Btw ...
1) What is the physical distance between your Client and your Server? Are they connected over the Internet?

They are at the same network, no internet.

2) Is it possible that there is a Proxy between the Client and the Server and the connection you are receiving at the Server actually came from the Proxy?

Yes. That can happens.

3) How did you close the connection on the Client side (terminated the Client or closed the Client app nromally or plugged the cable out) and how long did it take for the Server to receive the OnDisconnect event?

Normally I call a disconnect method. But it is possible that a user forces an abnormal termination of my app (killing the process). This way, the server will never get the disconnect call.

Best Regards,
Danijel Tkalcec