Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Oct : Re: Best method of keep-alive?

www.cryer.info
Managed Newsgroup Archive

Re: Best method of keep-alive?

Subject:Re: Best method of keep-alive?
Posted by:"Jamie Dale" (j.da..@turboz.net)
Date:Tue, 3 Oct 2006 16:50:25

"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:4521ab43$1@newsgroups.borland.com...
>
> "Jamie Dale" <j.dale@turboz.net> wrote in message
> news:45219211@newsgroups.borland.com...
>
>> > This has been discussed many many times before.  Please go to
>> > http://www.deja.com and search through the newsgroup archives.
>>
>> Goes to groups.google.com
>
> Yes, Google bought out Deja several years ago.  Google maintains the
> archives now.  They are fully intact, going back almost 10 years.

I see. Never knew that so please excuse my ignorance
>
>> Couldn't find anything about Indy there  :(
>
> Then you did not do a very detailed search, because there are TONS of
> Indy-related and socket-related questions in the Borland archives.  For
> example:
>
>
> http://groups.google.com/groups?lnk=hpsg&q=socket+keep+alive+group%3A*delphi*
>
>
> http://groups.google.com/groups/search?q=indy+keep+alive+group%3A*delphi*
>
> Learn to use the Advanced search options.  They are very flexible and very
> useful.

Thank you for the links - I'm sure they will prove very useful. With regards
to advanced search's I never really have a lot of luck with those. Dunno why
:(
>
>> Ok, so I can just adjust my Athread.Connecdtion.ReadLn
>> TO: AThread.Connection.ReadLn(', 60)   ???
>
> 60 milliseconds is much too short a time.

I realised that after posting it ;) - I was hoping you'd realise I meant
seconds lol.

> TCP latency could easily be
> longer than that without losing the connection.  I would suggest using 30
> seconds minumum.  Even better, use a 1 minute timout and then have the
> client send the ping every 30 seconds to ensure at least 1 ping makes it
> through to the server during the 1 minute window.

Ok thanks.
>
> With that said, yes you can use the ATimeout parameter to ReadLn(), or you
> can use the ReadTimeout property on the TIdTCPConnection object itself.
> Either way, just be sure to look at the ReadLnTimedOut property after
> ReadLn() exits.

I'm using Indy 8. ReadLnTimedOut doesn't exist. Do you have any other ideas
please?
>
>> This is my current OnExecute Method:
>
> Try this code:
>
>    procedure TDefaultServer.IdTCPServer1Execute(AThread: TIdPeerThread);
>    var
>        Command: String;
>    begin
>        Command := AThread.Connection.ReadLn('', 60000);
>        if AThread.Connection.ReadLnTimedOut then
>        begin
>            AThread.Connection.DisconnectSocket;
>            Exit;
>        end;
>        if AnsiSameText(Command, 'PING') then
>        begin
>            AThread.Connection.WriteLn('PONG');
>            Exit;
>        end;
>        if Pos('|', Command) <> 0 then
>        begin
>            // process command...
>            CommandEngine.ProcessCmd(Command, AThread);
>        end else
>        begin
>            // do something else ...
>        end;
>    end;

Thanks for the code - Apart from the ReadLnTimedOut, it has certainly given
me food for thought.
>> Why? - I was assuming it could be done by using a TTimer and
>> simply going through an array of AThreads and sending a 'ping' to
>> their connection? -
>
> That would require much more work to implement on the server side.  You
> would have to synchronize all of your writes to each client connection to
> ensure that the timer's pings do not overlap any responses that the
> threads
> happen to be writing at the same time, thus corrupting everything.

Yes, as always you are right. I get somewhat confused when working with
threads...

  It is a
> lot easier to just have the server be a passive responder to the client's
> pings instead of an active pusher of its own pings, and handle the ping
> replies in the same thread that receives them.

Ok
>
>> My thought was to use the serials to basically keep track of what
>> pings had received a reply....
>
> Completely unnecessary.

Agreed. Thanks to your input I see the light ;)
>
>> But supposing soem sort of accidental error has happened (god knows
> what)...
>
> Doesn't matter.  If the client sends a ping and it takes a long time for
> the
> reply to arrive, then the client should disconnect and reconnect after the
> ping has timed out.  That is the whole point of implementing a kepp alive
> to
> begin with - to detect when the connection is too slow, or has been lost
> altogether.

Which brings me to another point:
Should my client set a timer to expect a response within? - Seeing as I'm
now going to do this from the client end, I'm supposing that my client
should activate a timer when it sends 'ping' and then close the connection
if the timer expires before a reply is received?

I also noticed that the ReadLn procedure seems to be the same in
TIdTCPClient. I'm assuming that I could perhaps use this to my advantage for
waiting for the 'pong' reply?

>> if you don't give the client a 2nd chance then it could be wrongly
>> disconnected.
>
> All the more reason that the pings should be sent by each client
> individually instead of the server.  If a client does not send any data to
> the server in a timely manner, then the server can drop the connection
> with
> that client and release resources that could be used for other things.
> This
> is also the only way the server can detect clients being lost.  If the
> client is too slow, then tough.  The client has the responsibility to
> send/receive data as fast as it can, and to not block the communications
> unnecessarily.

Ok
>
> EG 56k modem utilising full bandwidth could block a ping
>
>> Or sending a file down the very same connection would make
>> it unusable for a while (until the file has finished).
>
> No, it wouldn't.  There are ways to multiplex multiple channels of
> communication over a single connection.  Although that is not really
> needed,
> since the presense of a file transfer on a connection is enough to act as
> that connection's keep-alive by itself.  The whole point of keep-alives is
> to make sure data is transferrable across the data.  The only reason to
> introduce 'ping'-style commands into the protocol is to deal with idle
> periods of inactivity from wrongs closing the connection between actual
> operations.

Cheers for your help Remy

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive