0

独自の Jabber ボットを作成しようとしていますが、少し問題が発生しました。ボットがメッセージに応答するようになりましたが、ボットのプレゼンスを変更しようとすると、ボットに送信するすべてのメッセージが遅延するように見えます。

つまり、スクリプトを実行するとプレゼンスが変更され、オンラインであることがわかります。次に、メッセージを送信すると、メッセージ用に設定したコールバック サブルーチンが呼び出されるまでに 3 時間かかります。3 番目のメッセージが送信され、chat サブルーチンが呼び出された後も、最初に送信したメッセージが処理されます。

これは、「ログアウト」メッセージを送信したときにログアウトするように設定していることと、ログアウトするためにさらに2つのメッセージが続く必要があることを除いて、それほど大きな問題を引き起こすことはありません. これを修正するために何をしなければならないのかわかりませんが、iq コールバックも設定しており、プレゼンスを設定した後に 2 回呼び出されるため、iq パケットに関係があると思います。

ここに私のソースコードがあります:

#!/usr/bin/perl

厳密に使用します。
警告を使用します。

#ライブラリ
Net::Jabber を使用します。
DBI を使用します。
DBD::mysql を使用します。

# --------------- 設定変数 -----------------
# Jabber クライアント
私の $jbrHostname = "ドメイン名";
my $jbrUserName = "ユーザー名";
私の $jbrPassword = "パスワード";
私の $jbrResource = "リソース";
私の $jbrBoss = 新しい Net::Jabber::JID();
$jbrBoss->SetJID(userid=>"USERNAME",server=>$jbrHostname);

# MySQL
私の $dbHostname = "ドメイン名";
私の $dbName = "データベース名";
my $dbUserName = "ユーザー名";
私の $dbPassword = "パスワード";
# --------------- 構成の終了 -----------------

# データベースに接続
my $dbh = DBI->connect("DBI:mysql:database=$dbName;host=$dbHostname",$dbUserName, $dbPassword, {RaiseError => 1}) or die "データベースに接続できませんでした: $ !\n";

# 新しい jabber クライアントを作成し、サーバーに接続します
私の $jabberBot = Net::Jabber::Client->new();
my $status = $jabberBot->Connect(hostname=>$jbrHostname) or die "接続できません ($!)\n";
私の @results = $jabberBot->AuthSend(username=>$jbrUserName,password=>$jbrPassword,resource=>$jbrResource);

if($results[0] ne "ok")
{
    die "Jabber 認証エラー @results\n";
}

# Jabber ボットのコールバックを設定
$jabberBot->SetMessageCallBacks(chat=>\&chat);
$jabberBot->SetPresenceCallBacks(available=>\&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=>"こんにちは!グローバル...",type=>"chat",priority=>10);
#$jabberBot->Process(5);
&続けて;

サブチャット
{
    print "チャットが呼び出されました!\n";
    私 ($sessionID,$msg) = @_;
    $jabberBot->MessageSend(to=>$msg->GetFrom(),subject=>"",body=>"チャット中!",type=>"チャット",priority=>10);
    if($msg->GetBody() ne 'ログアウト')
    {
        print $msg->GetBody()."\n";
        &続けて;
    }
    そうしないと
    {
        &killBot($msg);
    }

}

サブゴットIQ
{
    print $_[1]->GetID()."\n";
    &チャット;
}

サブkeepItGoing
{
    print "Movin' the chain!\n";
    私の $proc = $jabberBot->Process(1);
    while(定義済み($proc) && $proc != 1)
    {
        $proc = $jabberBot->Process(1);
    }
}

サブキルボット
{
    $jabberBot->MessageSend(to=>$_[0]->GetFrom(),subject=>"",body=>"Logging Out!",type=>"chat",priority=>10);
    $jabberBot->プロセス(1);
    $jabberBot->Disconnect();
    出口;
}

ご協力いただきありがとうございます!

4

2 に答える 2

0

次の行を置き換えます。

$jabberBot->Process(1);

これ等と一緒に:

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

keepItGoing ルーチンが原因で、リソースが不足しています。一般に、このように XMPP を同期的に使用しようとしてもうまくいきません。コールバックを設定してから、1 つのループで 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 への呼び出しを削除すると、期待どおりに動作するはずです。

于 2010-03-30T07:15:18.497 に答える