为什么我必须在注销之前将多条消息发送到我的Jabber机器人?

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

我的意思是,当我运行脚本时,我改变了状态,所以我可以看到它在线。 然后,当我发送一条消息时,在我为消息设置的回调子例程被调用之前需要三个消息。 发送第三条消息并调用聊天子例程后,它仍会处理我发送的第一条消息。

这实际上不会造成太多的问题,除非我在发送消息“注销”时设置为注销,并且必须紧接着两条消息才能注销。 我不确定我需要做些什么来解决这个问题,但我认为它与iq数据包有关,因为我也有一个iq回调集,并且在设置存在之后它会被调用两次。

这是我的源代码:

#!/usr/bin/perl

use strict;
use warnings;

#Libraries
use Net::Jabber;
use DBI;
use DBD::mysql;

#--------------- Config Vars -----------------
# Jabber Client
my $jbrHostname = "DOMAINNAME"; 
my $jbrUserName = "USERNAME";
my $jbrPassword = "PASSWORD";
my $jbrResource = "RESOURCE";
my $jbrBoss = new Net::Jabber::JID();
$jbrBoss->SetJID(userid=>"USERNAME",server=>$jbrHostname);

# MySQL
my $dbHostname = "DOMAINNAME";
my $dbName = "DATABASENAME";
my $dbUserName = "USERNAME";
my $dbPassword = "PASSWORD";
#--------------- End Config -----------------

# connect to the db
my $dbh = DBI->connect("DBI:mysql:database=$dbName;host=$dbHostname",$dbUserName, $dbPassword, {RaiseError => 1}) or die "Couldn't connect to the database: $!n";

# create a new jabber client and connect to server
my $jabberBot = Net::Jabber::Client->new();
my $status = $jabberBot->Connect(hostname=>$jbrHostname) or die "Cannot connect ($!)n";
my @results = $jabberBot->AuthSend(username=>$jbrUserName,password=>$jbrPassword,resource=>$jbrResource);

if($results[0] ne "ok")
{
    die "Jabber auth error @resultsn";
}

# set jabber bot callbacks
$jabberBot->SetMessageCallBacks(chat=>&chat);
$jabberBot->SetPresenceCallBacks(available=>&welcome);
$jabberBot->SetCallBacks(iq=>&gotIQ);

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

sub welcome
{
    $jabberBot->MessageSend(to=>$jbrBoss->GetJID(),subject=>"",body=>"Hello There!",type=>"chat",priority=>10);
    &keepItGoing;
}

$jabberBot->MessageSend(to=>$jbrBoss->GetJID(),subject=>"",body=>"Hello There! Global...",type=>"chat",priority=>10);
#$jabberBot->Process(5);
&keepItGoing;

sub chat
{
    print "Chat Called!n";
    my ($sessionID,$msg) = @_;
    $jabberBot->MessageSend(to=>$msg->GetFrom(),subject=>"",body=>"Chatting!",type=>"chat",priority=>10);
    if($msg->GetBody() ne 'logout')
    {
        print $msg->GetBody()."n";
        &keepItGoing;
    }
    else
    {
        &killBot($msg);
    }

}

sub gotIQ
{
    print $_[1]->GetID()."n";
    &chat;
}

sub keepItGoing
{
    print "Movin' the chains!n";
    my $proc = $jabberBot->Process(1);
    while(defined($proc) && $proc != 1)
    {
        $proc = $jabberBot->Process(1);
    }
}

sub killBot
{
    $jabberBot->MessageSend(to=>$_[0]->GetFrom(),subject=>"",body=>"Logging Out!",type=>"chat",priority=>10);
    $jabberBot->Process(1);
    $jabberBot->Disconnect();
    exit;
}

谢谢你的帮助!


由于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中那样杀死你。

在你的情况下,如果你从chat()中删除呼叫keepItGoing,我敢打赌事情会更像你期望的。


更换该行:

$jabberBot->Process(1);

用这些:

while (defined($jabberBot->Process(1))) {
    # Do stuff here
}
链接地址: http://www.djcxy.com/p/16809.html

上一篇: Why do I have to send multiple messages to my Jabber bot before it will logout?

下一篇: What are your favorite Mootools/Prototype native object prototypes?