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:Mon, 2 Oct 2006 23:26:30

"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:45217a36$1@newsgroups.borland.com...
>
> "Jamie Dale" <j.dale@turboz.net> wrote in message
> news:4521516d@newsgroups.borland.com...
>
>> I was wondering if anyone has a idea or method for implementing a
>> keep-alie system using TIdTCPClient and TIdTCPServer?
>
> 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 - Couldn't find anything about Indy there  :(

> Or go to
> Indy's own newsgroups on the news://news.atozed.com server and browse
> through the old messages that are still on the server (there are no
> archives
> for Indy's server).

Sure thing.... Not found anything yet, but I'll keep looking!

>> I'm pretty familiar with the general theory - One end can send a 'ping'
>> and the other replies with a 'pong'.
>
> Yes, that is one way to do it.

Glad I got something right ;)

>> My question is what is the best way to do this
>
> There is no "best" way to implement it.  It is whatever you are
> comfortable
> with, and what fits into your actual protocol.

Ok that makes me feel a little more confident

>> how can one end of the connection recognise if the time for
>> the reply has expired?
>
> It is each side's responsibility to keep track of how much time has
> elapsed
> between packets.  In general, you need to take advance of the connection's
> ReadTimeout property to know when no data has arrived for a given period
> of
> time.

Ok, so I can just adjust my Athread.Connecdtion.ReadLn
TO: AThread.Connection.ReadLn(', 60)   ???

This is my current OnExecute Method:
procedure TDefaultServer.IdTCPServer1Execute(AThread: TIdPeerThread);
//Things to do when server executed: EG something recv'd
var
Command: String;
begin
//Read Command/Message when it arrives
Command := AThread.Connection.ReadLn;

//If Command/Message is not blank and contains '¦' character
If (Command <> '') and (Pos('¦', Command) <> 0) then
    begin
    //Process Commands
    CommandEngine.ProcessCmd(Command, AThread);
    end;
end;

Can I instead simply do this?:

procedure TDefaultServer.IdTCPServer1Execute(AThread: TIdPeerThread);
//Things to do when server executed: EG something recv'd
var
Command: String;
begin
//Read Command/Message when it arrives
Command := AThread.Connection.ReadLn('', 60);

//If Command/Message is not blank and contains '¦' character
If (Command <> '') and (Pos('¦', Command) <> 0) then
    begin
    //Process Commands
    CommandEngine.ProcessCmd(Command, AThread);
    end;

If UpperCase(Command) = 'PING' then
    begin
    AThread.Connection.WriteLn('Pong');
    end
else
    If Command = '' then
        begin
        AThread.Connection.Disconnect;
        end;
end;
>> 1) Server sends 'ping' with a serial number - IE Ping := 'ping:123';
>
> The client should be the one to send the pings, not the server.

Ok..

> This way,
> the client is actively telling the server that it wishes to remain
> connected
> to the server.  If the server does not receive the ping for a given period
> of time, it can close the connection.

Ok..

> If the server were the one to send
> the pings, then it does not work as well.

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? -
Maybe a sloppy way of doing it but I thought it should work ;)

> Also, you don't need serial numbers in the pings at all, since the server
> would only be interested in knowing that data is still flowing through the
> connection in general, not necessarily what the data actually is.

Very good point!... My thought was to use the serials to basically keep
track of what pings had received a reply....

>> Client does not respond. Timer kicks in and checks array for replies
>> that are outstanding and increments a count.
>
> Since Indy servers are multi-threaded to begin with, there is no need for
> a
> ping array.  Each individual thread can manage its own ping locally.

Ok still not sure exactly how to deal with that but I'm hoping the code
above will work!

>> Server then sends the same ping/serial again.
>
> If a ping is not replied to in a timely manner, the ping should not be
> attempted again.  Simply disconnect the connection immediately.  The
> client
> can then reconnect to the server if it wishes to.

But supposing soem sort of accidental error has happened (god knows what)...
if you don't give the client a 2nd chance then it could be wrongly
disconnected. 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). How would I deal with this?

Remy, as always, Thanks for your expert help.

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive