2

IndyのIRCコンポーネント(TIdIRC)に基づいてコンソールアプリケーションを作成しようとしていますが、イベントに問題があります。これが私のコードです:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes,
  Math,
  IdBaseComponent,
  IdComponent,
  IdTCPConnection,
  IdTCPClient,
  IdIRC;

type
  TEvents = class
  public
    procedure Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);
  end;

const
  IrcServ = 'gr.irc.gr';
  IrcPort = 6667;
  IrcChan = '#lalala';

var
  Irc: TidIRC;
  Event: TEvents;
  uName, rName: string;

function Log(s: string): string;
var now: TDateTime;
begin
  now := Time;
  result := FormatDateTime('[hh:nn:ss] ', now) + s;
end;

procedure TEvents.Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);
begin
  Log(AUser.Nick+' '+ACommand+' '+AContent);
end;

begin
  Event := TEvents.Create;
  Irc := TidIRC.Create(nil);
  Irc.OnRaw := Event.Raw;
  Randomize;
  Write('Nickname: ');
  ReadLn(uName);
  rName := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
  with Irc do begin
    AltNick := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
    Nick := rName;
    Username := rName;
    RealName := 'I.D.M.';
    Host := IrcHost;
    Port := IrcPort;
    //MaxLineAction := maException;  <-- [ERROR] Undeclared identifier: 'maException'
    ReadTimeout := 0;
    UserMode := [];
    Connect();
    Join(IrcChan);
  end;
  ReadLn;

end.

これまで考えられることはすべて試しましたが、アプリは正常に接続されていますが、生のメッセージは返されません...何が欠けていますか?

4

1 に答える 1

4

TdIRC内部ワーカースレッドを使用してデータを受信します。このOnRawイベントは、そのスレッドがデータを解析しているときにトリガーされます。スレッドはTThread.Synchronize()その解析を行うために使用します。メインスレッドにはアクティブなVCLメッセージループがないため、Synchronize()キューを手動でポンピングできます。接続後、IRCに接続しているときに、ユニットからループでCheckSynchronize()関数を呼び出します。例:Classes

begin 
  ...
  Connect; 
  try
    Join(IrcChan); 
    do
      CheckSynchronize;
      Sleep(10);
    until SomeCondition;
  finally
    Disconnect;
  end;
  ...  
end. 

適切な方法として、ユニット内のWakeMainThreadイベントにハンドラーを割り当てて、いつ呼び出す必要があるかを制御できるようにすることができます。これにより、IRC接続がアイドル状態のときに、メインスレッドがスリープ状態になります。ClassesCheckSynchronize()

program Project1;     

{$APPTYPE CONSOLE}     

uses     
  SysUtils,     
  Classes,     
  Math,     
  IdBaseComponent,     
  IdComponent,     
  IdTCPConnection,     
  IdTCPClient,     
  IdIRC;     

type     
  TEvents = class     
  private
    FSyncEvent: TEvent;
  public     
    constructor Create;
    destructor Destroy; override;
    procedure Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);     
    procedure Wake(Sender: TObject);
    procedure CheckSync;
  end;     

function Log(s: string): string;      
begin      
  result := FormatDateTime('[hh:nn:ss] ', Time) + s;      
end;      

constructor TEvents.Create;
begin
  inherited;
  FSyncEvent := TEvent.Create(nil, False, False, '');
end;

destructor TEvents.Destroy;
begin
  FSyncEvent.Free;
  inherited;
end;

procedure TEvents.Raw(Sender: TObject; AUser: TIdIRCUser; ACommand, AContent: String; var Suppress: Boolean);      
begin      
  Log(AUser.Nick+' '+ACommand+' '+AContent);      
end;      

procedure TEvents.Wake(Sender: TObject);
begin
  FSyncEvent.SetEvent;
end;

procedure TEvents.CheckSync;
begin
  FSyncEvent.WaitFor(Infinite);
  CheckSynchronize;
end;

const     
  IrcServ = 'gr.irc.gr';     
  IrcPort = 6667;     
  IrcChan = '#lalala';     

var      
  Irc: TidIRC;      
  Event: TEvents;      
  uName, rName: string;      

begin
  Event := TEvents.Create;       
  try
    WakeMainThread := Event.Wake;
    Irc := TIdIRC.Create(nil);       
    try
      Irc.OnRaw := Event.Raw;       
      Randomize;       
      Write('Nickname: ');       
      ReadLn(uName);       
      rName := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;       
      with Irc do begin       
        AltNick := 'IDM' + IntToStr(RandomRange(1000, 9999)) + uName;
        Nick := rName;       
        Username := rName;       
        RealName := 'I.D.M.';       
        Host := IrcHost;       
        Port := IrcPort;       
        //MaxLineAction := maException;  <-- [ERROR] Undeclared identifier: 'maException'       
        ReadTimeout := 0;       
        UserMode := [];       
        Connect;       
        try
          Join(IrcChan);       
          do
            Event.CheckSync;
          until SomeCondition;
        finally
          Disconnect;
        end;
      end;       
    finally
      Irc.Free;
    end;
  finally
    Event.Free;
  end;
end.
于 2012-07-06T16:30:25.333 に答える