Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Oct : 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