我正在尝试使用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.
到目前为止,我已经尝试了所有我能想到的,但是,虽然应用程序已成功连接,但它不会返回任何原始消息...我缺少什么?
答案 0 :(得分: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
单元中的Classes
事件分配处理程序,以帮助控制何时应调用CheckSynchronize()
,以便主线程可以进入休眠状态IRC连接空闲,例如:
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.