Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TIdCmdTCPServer customised Reply
#2
(01-24-2019, 01:07 PM)jollytall Wrote: On the client side I have (properly built it Try..Except, etc, what I do not include here):

Code:
Log(IntToStr(IdTCPClient1.SendCmd('AAA 1',[200])));
Log(IdTCPClient1.LastCmdResult.DisplayName);

where Log is a procedure to display a string.

Note, in the above code, if SendCmd() receives any reply code other than 200, it will raise an exception, skipping your logging. If you don't want that to happen (or if you at least want to log the reply code before raising the exception) then don't specify any reply codes to SendCmd() and it will return the actual reply code received. You can use TIdTCPConnection.CheckResponse() afterwards (amongst others) to trigger the exception manually if needed:

Code:
IdTCPClient1.SendCmd('AAA 1');
Log(IdTCPClient1.LastCmdResult.DisplayName);
IdTCPClient1.CheckResponse(IdTCPClient1.LastCmdResult.NumericCode, [200]);

Otherwise, consider using the TIdTCPClient.Intercept property instead to log your command/response traffic. Indy has several TIdLog... components for intercepting traffic, such as TIdLogEvent, for instance:

Code:
// these can all be set at design-time, too...
IdTCPClient1.Intercept := IdLogEvent1;
IdLogEvent1.OnReceived := IdLogEvent1Received;
IdLogEvent1.Active := True;
...
IdTCPClient1.SendCmd('AAA 1', [200]);
...
procedure TMyForm.IdLogEvent1Received(ASender: TComponent; const AText, AData: string);
begin
  Log(AData);
end;

(01-24-2019, 01:07 PM)jollytall Wrote: On the server side I have (again properly built around):

Code:
procedure TMyIdCmdTCPServer.OnCommandAAA(ASender: TIdCommand);
begin
 Log('Raw Line ' + ASender.RawLine);
 ASender.Reply.Text.Text := 'DT= ' + DateTimeToStr(Now);
end;

You are not setting a reply code in that handler, so the NormalReply property of the TIdCommandHandler of the 'AAA' command will be used by default, if you have defined a reply code for it. Which is perfectly fine, I'm just pointing it out.

(01-24-2019, 01:07 PM)jollytall Wrote: After connecting I send the comand from the client. What I get is "200 Welcome", what is obviously the default welcome message.

Yes, that is the default greeting for TIdCmdTCPServer. Many Internet protocols have server greetings, so a client can verify that it is connected to the proper type of server, amongst other things, before continuing.

If you do not want your server to send a greeting, simply clear the contents of the TIdCmdTCPServer.Greeting property (or, at least set the Greeting.Code property to a blank string) so there is nothing for the server to send. You will have to do this at run-time, though, eg:

Code:
procedure TMyForm.FormCreate(Sender: TObject);
begin
  IdCmdTCPServer1.Greeting.SetReply('', '');
end;

Or:

Code:
procedure TMyForm.FormCreate(Sender: TObject);
begin
  IdCmdTCPServer1.Greeting.Code := '';
end;

If you try to clear the Greeting at design-time, it won't preserve correctly when the DFM is streamed, so the default '200 Welcome' will re-appear (I'll have to look into that).

Otherwise, the client will need to read the greeting before sending any commands. You can use TIdTCPClient.GetResponse() for that:

Code:
IdTCPClient1.Connect;
IdTCPClient1.GetResponse(200); // read greeting
IdTCPClient1.SendCmd('AAA', [200]);

(01-24-2019, 01:07 PM)jollytall Wrote: If I send the Cmd again, from the same connect-disconnect session, then I get the proper DT= reply, with the Time of the PREVIOUS call.

Yes, because that earlier reply ends up sitting unread in the socket's inbound buffer until the next SendCmd() reads it (leaving THAT reply in the buffer for the next SendCmd() to read).

(01-24-2019, 01:07 PM)jollytall Wrote: So it is clear that the Reply.Text is set, but only after the Reply is sent to the client.

Not true. The reply is sent to your client as soon as your OnCommand handler exits. You are simply not taking into account that the server's initial greeting is being sent first and your client is reading the server's responses in the wrong order because of it.

(01-24-2019, 01:07 PM)jollytall Wrote: What do I do wrong? How can I customise the Reply AFTER the Cmd is received (so i know what the question is) but BEFORE it is sent back to the client?

You are not doing anything wrong on the server side. It is your client side that is at fault, by not reading the server's greeting properly. So, either read the greeting, or disable it. Then your code will behave properly as expected.

Reply


Messages In This Thread
TIdCmdTCPServer customised Reply - by jollytall - 01-24-2019, 01:07 PM
RE: TIdCmdTCPServer customised Reply - by rlebeau - 01-24-2019, 09:17 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)