0

我正在尝试制作自己的 Jabber 机器人,但遇到了一些麻烦。我已经让我的机器人响应消息,但是,如果我尝试更改机器人的存在,那么您发送给机器人的所有消息似乎都会延迟。

我的意思是,当我运行脚本时,我会更改存在,以便我可以看到它在线。然后,当我向它发送一条消息时,我为消息设置的回调子例程需要三个时间才能被调用。在发送第三条消息并调用聊天子例程后,它仍会处理我发送的第一条消息。

这实际上并没有造成太大的问题,只是我将它设置为在我发送消息“注销”时注销,并且必须在它之后再发送两条消息才能注销。我不确定我必须做些什么来解决这个问题,但我认为它与 iq 数据包有关,因为我也设置了 iq 回调,并且在设置存在后它会被调用两次。

这是我的源代码:

#!/usr/bin/perl

使用严格;
使用警告;

#图书馆
使用 Net::Jabber;
使用 DBI;
使用 DBD::mysql;

#--------------- 配置变量 -----
# Jabber 客户端
我的 $jbrHostname = "域名";
我的 $jbrUserName = "用户名";
我的 $jbrPassword = "密码";
我的 $jbrResource = "资源";
我的 $jbrBoss = new Net::Jabber::JID();
$jbrBoss->SetJID(userid=>"USERNAME",server=>$jbrHostname);

# MySQL
我的 $dbHostname = "域名";
我的 $dbName = "数据库名称";
我的 $dbUserName = "用户名";
我的 $dbPassword = "密码";
#--------------- 结束配置 -----

# 连接到数据库
我的 $dbh = DBI->connect("DBI:mysql:database=$dbName;host=$dbHostname",$dbUserName, $dbPassword, {RaiseError => 1}) 或 die "无法连接到数据库:$ !\n";

# 创建一个新的 jabber 客户端并连接到服务器
我的 $jabberBot = Net::Jabber::Client->new();
我的 $status = $jabberBot->Connect(hostname=>$jbrHostname) 或死 "无法连接 ($!)\n";
我的@results = $jabberBot->AuthSend(username=>$jbrUserName,password=>$jbrPassword,resource=>$jbrResource);

if($results[0] ne "ok")
{
    die "Jabber 身份验证错误@results\n";
}

# 设置 jabber bot 回调
$jabberBot->SetMessageCallBacks(chat=>\&chat);
$jabberBot->SetPresenceCallBacks(可用=>\&welcome);
$jabberBot->SetCallBacks(iq=>\&gotIQ);

$jabberBot->PresenceSend(type=>"available");
$jabberBot->进程(1);

子欢迎
{
    $jabberBot->MessageSend(to=>$jbrBoss->GetJID(),subject=>"",body=>"你好!",type=>"chat",priority=>10);
    &保持下去;
}

$jabberBot->MessageSend(to=>$jbrBoss->GetJID(),subject=>"",body=>"Hello There! Global...",type=>"chat",priority=>10);
#$jabberBot->进程(5);
&保持下去;

子聊天
{
    打印“已调用聊天!\n”;
    我的 ($sessionID,$msg) = @_;
    $jabberBot->MessageSend(to=>$msg->GetFrom(),subject=>"",body=>"正在聊天!",type=>"chat",priority=>10);
    if($msg->GetBody() ne '注销')
    {
        打印 $msg->GetBody()."\n";
        &保持下去;
    }
    别的
    {
        &killBot($msg);
    }

}

子得到IQ
{
    打印 $_[1]->GetID()."\n";
    &聊天;
}

子 keepItGoing
{
    print "Movin' the chain!\n";
    我的 $proc = $jabberBot->Process(1);
    而(定义($proc)&& $proc!= 1)
    {
        $proc = $jabberBot->进程(1);
    }
}

子杀戮机器人
{
    $jabberBot->MessageSend(to=>$_[0]->GetFrom(),subject=>"",body=>"注销!",type=>"chat",priority=>10);
    $jabberBot->进程(1);
    $jabberBot->断开连接();
    出口;
}

谢谢你的帮助!

4

2 回答 2

0

由于您的 keepItGoing 例程,您的资源匮乏。一般来说,尝试像这样同步使用 XMPP 是行不通的。我建议设置你的回调,然后在一个循环中调用 Process()。

Process() 的文档说:

Process(integer) - takes the timeout period as an argument.  If no
                   timeout is listed then the function blocks until
                   a packet is received.  Otherwise it waits that
                   number of seconds and then exits so your program
                   can continue doing useful things.  NOTE: This is
                   important for GUIs.  You need to leave time to
                   process GUI commands even if you are waiting for
                   packets.  The following are the possible return
                   values, and what they mean:

                       1   - Status ok, data received.
                       0   - Status ok, no data received.
                     undef - Status not ok, stop processing.

                   IMPORTANT: You need to check the output of every
                   Process.  If you get an undef then the connection
                   died and you should behave accordingly.

每次调用 Process() 时,都会触发 0 个或多个回调。你永远不知道哪个,因为它取决于服务器时间。如果您希望 Process() 在发送某些内容之前返回,您几乎总是在同步思考,而不是在 XMPP 中杀死您的 asych。

在您的情况下,如果您从 chat() 中删除对 keepItGoing 的调用,我敢打赌事情会像您期望的那样工作。

于 2010-03-30T07:15:18.497 回答
0

换行:

$jabberBot->Process(1);

用这些:

while (defined($jabberBot->Process(1))) {
    # Do stuff here
}
于 2010-05-10T20:47:33.863 回答