クライアント(IdTCPClient)に、必要に応じてサーバー(IdTCPServer)にメッセージを送信させることができました。しかし、どうすればクライアントに応答を待つか、適切にタイムアウトさせることができますか?
乾杯、エイドリアン
クライアントはIOHandler.Readxxxメソッドを使用して応答を読み取ることができ、それらのほとんどはタイムアウトを設定できます。読み取りタイムアウトは、IdTCPClient.IOHandlerで直接指定することもできます。
procedure TForm1.ReadTimerElapsed(Sender: TObject);
var
S: String;
begin
...
// connect
IdTCPClient1.Connect;
// send data
...
// use one of the Read methods to read the response.
// some methods have a timeout parameter,
// and others set a timeout flag
S := IdTCPClient1.IOHandler.ReadLn(...);
if IdTCPClient1.IOHandler.ReadLnTimedOut then
...
else
...
end;
例えば:
クライアント:
procedure TForm1.SendCmdButtonClick(Sender: TObject);
var
Resp: String;
begin
Client.IOHandler.WriteLn('CMD');
Resp := Client.IOHandler.ReadLn;
end;
サーバ:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
Cmd: String;
begin
Cmd := AContext.Connection.IOHandler.ReadLn;
...
AContext.Connection.IOHandler.WriteLn(...);
end;
TIdTCPConnection.SendCmd()
または、代わりに次の方法を使用できます。
クライアント:
procedure TForm1.SendCmdButtonClick(Sender: TObject);
begin
// any non-200 reply will raise an EIdReplyRFCError exception
Client.SendCmd('CMD', 200);
// Client.LastCmdResult.Text will contain the response text
end;
サーバ:
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
Cmd: String;
begin
Cmd := AContext.Connection.IOHandler.ReadLn;
...
if (Command is Successful) then
AContext.Connection.IOHandler.WriteLn('200 ' + ...);
else
AContext.Connection.IOHandler.WriteLn('500 Some Error Text here');
end;
この後者のシナリオでは、に切り替えると、イベントを使用してコマンドを手動で読み取って解析する代わりにTIdCmdTCPServer
、コレクションを使用TIdCmdTCPServer.CommandHandlers
して設計時にコマンドを定義し、コマンドごとのイベントハンドラーを割り当てることができます。OnCommand
OnExecute
// OnCommand event handler for 'CMD' TIdCommandHandler object...
procedure TForm1.IdCmdTCPServer1CMDCommand(ASender: TIdCommand);
begin
...
if (Command is Successful) then
ASender.Reply.SetReply(200, ...);
else
ASender.Reply.SetReply(500, 'Some Error Text here');
end;
Indyコンポーネント(またはDelphi)を使用してからしばらく経ちましたが、TIdTCPClientは非同期で動作しないため、設定できるOnDataまたは同様のイベントはないと思います。
ReadLn(...)などの親クラス(TIdTCPConnection)から読み取りメソッドの1つを呼び出す必要があります。または、TIdTCPClientの子孫である多くのIndyコンポーネントの1つを使用することを検討できます。
クラスのドキュメントはここにあります。