なぜ私はそれがログアウトする前に私のJabberボットに複数のメッセージを送信することがありますか?

StackOverflow https://stackoverflow.com/questions/2535577

質問

私は自分のJabberボットを作成しようとしていますが、私は少しトラブルに遭遇してきました。私は、ボットの存在を変更しようとする場合は、遅れが出るボットに送信するメッセージのすべてかのようにしかし、それはそうと、メッセージに応答する私のボットを頂いております。

私、私は、私はそれがオンラインであることを見ることができますので、私は存在を変更するスクリプトを実行するときの平均です。その後、私はそれを私がメッセージを設定したコールバックサブルーチンが呼び出される前に、それは3を取るメッセージを送信するとき。 thirrdメッセージが送信されると、チャットサブルーチンが呼び出された後、それはまだ私が送られた最初のメッセージを処理します。

これは本当に私はそれが私がメッセージ「ログアウト」を送信するときにログアウトするように設定していると、それはログアウトするために2件の以上のメッセージが続く必要があることを除いてあまり問題になりません。私はそれが私がこの問題を解決するためにしなければならないが、私は、私は、IQのコールバックを設定しているだけでなく、それが存在することを設定した後に2回呼び出されるので、それが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 @results\n";
}

# 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を使用しようとしています。私はあなたのコールバックが設定取得提案、そしてちょうどの 1 のループで処理を()を呼び出します。

プロセス用ドキュメント()と言うます:

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.

あなたがプロセス(呼び出すたびに)、あなたのコールバックの0以上が発生します。それは、サーバーのタイミングに依存するため、あなたは、どの知っていることはありません。あなたが何かを送信する前に戻すために)(プロセスのために必要がある場合は、ほとんど常にXMPPであなたを殺す、というよりもasych、同期考えている。

あなたがチャット()からkeepItGoingへの呼び出しを削除する場合は

あなたのケースでは、私は物事はより多くのあなたが期待するように動作します賭けます。

他のヒント

の行を置き換えます:

$jabberBot->Process(1);
これらと

while (defined($jabberBot->Process(1))) {
    # Do stuff here
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top