2
votes

Is it possible to make my TCPServer.OnExecute event behave the same way as HTTPServer.OnCommandGet behaves :

procedure TMainForm.HttpServerCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  AResponseInfo.ResponseNo := 200;
  AResponseInfo.ContentType := 'text/plain';
  AResponseInfo.ContentText := 'Hello';
end; 

I tried this :

procedure TMainForm.TCPServerExecute(AContext: TIdContext);
begin
  AContext.Connection.IOHandler.WriteLn('Hello');
end;

but it sends 'Hello' to the browser infinite times until I make the server inactive.

2

2 Answers

2
votes

TIdHTTPServer does not trigger an OnCommand... event until it has read a complete HTTP request from the client.

Your TIdTCPServer is not reading any requests at all.

TIdTCPServer.OnExecute is a looped event. It is triggered continuously for the lifetime of the connection. It is the event handler's responsibility to decide what to do on each loop iteration, and provide any necessary reading/writing logic that is appropriate for the communication protocol being implemented.

In your example, all you are doing is writing a line of text on each loop iteration, which is why you are seeing endless lines appear in the browser. Your event handler logic needs to be more structured than that. That is what protocols are all about. And in your case, since you are communicating with a web browser, you need to implement the HTTP protocol (which is what TIdHTTPServer does for you).

1
votes

The execute method is called in a loop for the duration of the TCP connection. This would be ok for a server push application (except that the message sending should be throttled to avoid overloading the server).

If you want to implement a request/reply protocol, start with a ReadLn (or any other Read method which matches your protocol). This will block execution until the client has sent a request.