Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 May : Newsserver disconnects - how to notice this
| Subject: | Newsserver disconnects - how to notice this |
| Posted by: | "Shiva" (shi..@gonzo.com) |
| Date: | Tue, 2 May 2006 20:11:05 |
Hi,
My program acts as a proxy / gateway between a client like Outlook Express
(OE) and my ISP's newsserver. Any NNTP-command send by OE is sent to my
program; the program sends the command to the newsserver and the response
messages of the newsserver are sent back to OE (the only exception is the
NNTP-command POST, this command is intercepted and its data is sent to a
mail2news gateway).
I've used a TIdTCPServer component to achieve this and everything works fine
except for the situation when the newsserver decides to disconnect after
being idle for a couple of minutes (the response is: "400
text.nova.planet.nl: Idle timeout." and then it disconnects). The
disconnection cannot be noticed by OE, because it is connected to my
program, not to the newsserver. Unfortunately, I am not able to trigger an
event once the server disconnects (anyway, I don't know how to do that!).
The connection to the newsserver is stored in a TIdPeerThread descendant
called TMyNNTPThread. It's the field fNewsserverISP.
The source of this class look like this:
TMyNNTPThread = class(TIdPeerThread)
private
fNewsserverISP: TIdTCPClient;
fMail2News: TIdSMTP;
public
constructor Create(ACreateSuspended: boolean); override;
destructor Destroy; override;
procedure Connect(const AHost: String; APort: Integer; aReconnect:
boolean);
procedure Disconnect;
property NewsserverISP: TIdTCPClient read fNewsserverISP;
property Mail2News: TIdSmtp read fMail2News;
end;
implementation
constructor TMyNNTPThread.Create(ACreateSuspended: boolean);
begin
fNewsserverISP := TIdTCPClient.Create(nil);
fMail2News := TIdSmtp.Create(nil);
fMail2News.Host := 'mail.planet.nl';
fMail2News.Port := 25;
inherited Create(ACreateSuspended);
end;
destructor TMyNNTPThread.Destroy;
begin
LogMessage('Before freeing fMail2News');
FreeAndNil(fMail2News);
LogMessage('After freeing fMail2News');
FreeAndNil(fNewsserverISP);
inherited Destroy;
end;
procedure TMyNNTPThread.Connect(const AHost: String; APort: Integer;
aReconnect: boolean);
var
s: string;
begin
fNewsserverISP.Host := AHost;
fNewsserverISP.Port := APort;
fNewsserverISP.Connect;
s := fNewsserverISP.ReadLn;
if not aReconnect then
Connection.WriteLn(s);
LogMessage('Connect='+ s);
end;
procedure TMyNNTPThread.Disconnect;
begin
if fNewsserverISP.Connected then begin
LogMessage('Disconnect, fNewsserverISP.Connected = true');
fNewsserverISP.Disconnect;
end
else
LogMessage('Disconnect, fNewsserverISP.Connected = false');
end;
OE does not notice the disconnection so I guess it assumes the connection is
still active, iow it does not try to reestablish the connection. OE then
receives the 400 response and display the message "Outlook Express was
unable to switch to the newsgroup alt.test" (that's what I wanted to do).
So the question is: how can I pass the disconnection to OE? Or should I keep
the connection alive by sending commands like "MODE READER" to the
newsserver? If so, what's the best way to do this?
By the way, this is what the execute handler of TIdTCPServer looks like:
procedure TFormMain.Exec(AThread: TIdPeerThread);
Var ClientNNTPLine, ResponseNewsserverISP: string;
ClientConn: TIdTCPServerConnection;
ii: integer;
NewsserverISP: TIdTCPClient;
begin
NewsserverISP := TMyNNTPThread(AThread).NewsserverISP;
ClientConn := TMyNNTPThread(AThread).Connection;
ClientNNTPLine := ClientConn.ReadLn;
LogMessage('ClientNNTPLine ='+ ClientNNTPLine);
if Pos('POST', ClientNNTPLine) = 1 then
GetPostAndSend2Mail2News(AThread)
else begin
NewsserverISP.WriteLn(ClientNNTPLine);
ResponseNewsserverISP := NewsserverISP.ReadLn;
LogMessage('Response ISP=' + ResponseNewsserverISP);
ClientConn.WriteLn(ResponseNewsserverISP);
if (Pos('215', ResponseNewsserverISP) = 1)
or (Pos('220', ResponseNewsserverISP) = 1)
or (Pos('221', ResponseNewsserverISP) = 1)
or (Pos('222', ResponseNewsserverISP) = 1)
or (Pos('223', ResponseNewsserverISP) = 1)
or (Pos('224', ResponseNewsserverISP) = 1)
or (Pos('231', ResponseNewsserverISP) = 1)
or (Pos('282', ResponseNewsserverISP) = 1) then begin
repeat
ResponseNewsserverISP := NewsserverISP.ReadLn;
LogMessage('Response ISP (>1) =' + ResponseNewsserverISP);
if ClientConn.Connected
and (not athread.Stopped) then
ClientConn.WriteLn(ResponseNewsserverISP);
until ResponseNewsserverISP = '.';
end
else
if Pos('400', ResponseNewsserverISP) = 1 then begin
TMyNNTPThread(AThread).NewsserverISP.Disconnect;
TMyNNTPThread(AThread).Disconnect;
end;
end;
end;
Thanks in advance!