作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个基于 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.
到目前为止,我已经尝试了我能想到的一切,但是,尽管应用程序已成功连接,但它不会返回任何原始消息......我错过了什么?
最佳答案
TdIRC
使用内部工作线程来接收数据。当该线程解析数据时,会触发 OnRaw
事件。线程使用TThread.Synchronize()
来进行解析。由于您的主线程没有事件的 VCL 消息循环,因此您可以手动泵入 Synchronize()
队列。连接后,在连接到 IRC 时,从 Classes
单元循环调用 CheckSynchronize()
函数,例如:
begin
...
Connect;
try
Join(IrcChan);
do
CheckSynchronize;
Sleep(10);
until SomeCondition;
finally
Disconnect;
end;
...
end.
为了更好地衡量,您可以为 Classes
单元中的 WakeMainThread
事件分配一个处理程序,以帮助控制何时应执行 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.
关于德尔福7 : Handling events in console application (TidIRC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11364434/
我正在尝试创建一个基于 Indy 的 IRC 组件 (TIdIRC) 的控制台应用程序,但我在处理事件时遇到了问题。这是我的代码: program Project1; {$APPTYPE CONSOL
我是一名优秀的程序员,十分优秀!