How to continuously send messages with TIdTCPServer?

前端 未结 2 1117
无人及你
无人及你 2021-01-14 03:50

I need to create a delphi application where when it\'s started the server is started as well and starts sending messages immediately, but I haven\'t found an example or tuto

2条回答
  •  庸人自扰
    2021-01-14 03:57

    Server push example application form

    This example uses a Delphi 2009 VCL application with a main form, which contains only one visual component, a TMemo named “MemoLog”.

    Client and server are both started in the FormCreate event. Note that the client code does not handle connection loss, but this can be implemented with a separate re-connect loop within the thread.

    procedure TServerPushExampleForm.FormCreate(Sender: TObject);
    begin
      ExampleServer := TMyPushServer.Create;
      ExampleServer.DefaultPort := 8088;
      ExampleServer.Active := True;
    
      ExampleClient := TMyPushClientThread.Create('localhost', 8088,
        MemoLog.Lines);
    end;
    

    Server

    The server code uses a TIdTCPCustomServer subclass which waits for a random time and then sends a string to the client.

    function TMyPushServer.DoExecute(AContext: TIdContext): Boolean;
    begin
      Result := inherited;
    
      // simulate hard work
      Sleep(Random(3000));
    
      AContext.Connection.IOHandler.WriteLn(
        'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8);
    end;
    

    Client

    The client code uses a TThread subclass to run asynchronously without blocking the main VCL thread. It contains a private TIdTCPClient instance, and periodically tries to receive a string from the connection.

    ...
      S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
    ...
    

    Full Delphi Form Code

    Below is the full code for the example main form.

    unit Unit1;
    
    interface
    
    uses
      IdCustomTCPServer, IdTCPClient, IdContext,
      SysUtils, Classes, Forms, StdCtrls, Controls;
    
    type
      TMyPushClientThread = class(TThread)
      private
        TCPClient: TIdTCPClient;
        FLog: TStrings;
      public
        constructor Create(AHost: string; APort: Word; ALog: TStrings);
        destructor Destroy; override;
        procedure Execute; override;
      end;
    
      TMyPushServer = class (TIdCustomTCPServer)
      protected
        function DoExecute(AContext: TIdContext): Boolean; override;
      end;
    
      TServerPushExampleForm = class(TForm)
        MemoLog: TMemo;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        ExampleClient: TMyPushClientThread;
        ExampleServer: TMyPushServer;
      end;
    
    var
      ServerPushExampleForm: TServerPushExampleForm;
    
    implementation
    
    uses
      IdGlobal;
    
    {$R *.dfm}
    
    procedure TServerPushExampleForm.FormCreate(Sender: TObject);
    begin
      ExampleServer := TMyPushServer.Create;
      ExampleServer.DefaultPort := 8088;
      ExampleServer.Active := True;
    
      ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines);
    end;
    
    procedure TServerPushExampleForm.FormDestroy(Sender: TObject);
    begin
      ExampleServer.Free;
      ExampleClient.Terminate;
      ExampleClient.WaitFor;
      ExampleClient.Free;
    end;
    
    { TMyPushServer }
    
    function TMyPushServer.DoExecute(AContext: TIdContext): Boolean;
    begin
      Result := inherited;
    
      // simulate hard work
      Sleep(Random(3000));
    
      AContext.Connection.IOHandler.WriteLn(
        'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8);
    end;
    
    { TMyPushClientThread }
    
    constructor TMyPushClientThread.Create(AHost: string; APort: Word; ALog: TStrings);
    begin
      inherited Create(False);
    
      FLog := ALog;
    
      TCPClient := TIdTCPClient.Create;
      TCPClient.Host := AHost;
      TCPClient.Port := APort;
      TCPClient.ReadTimeout := 500;
    end;
    
    destructor TMyPushClientThread.Destroy;
    begin
      TCPClient.Free;
      inherited;
    end;
    
    procedure TMyPushClientThread.Execute;
    var
      S: string;
    begin
      TCPClient.Connect;
    
      while not Terminated do
      begin
        S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
    
        if not TCPClient.IOHandler.ReadLnTimedout then
        begin
          TThread.Queue(nil,
            procedure
            begin
              FLog.Append(S);
            end);
        end;
    
      end;
    
      TCPClient.Disconnect;
    end;
    
    end.
    

    (From https://mikejustin.wordpress.com/2014/04/19/indy-10-tidtcpserver-server-side-message-push-example/)

提交回复
热议问题