لماذا يجب علي إرسال رسائل متعددة إلى روبوت Jabber الخاص بي قبل تسجيل الدخول؟

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

سؤال

أحاول صنع روبوت Jabber الخاص بي لكنني واجهت مشكلة صغيرة. لقد حصلت على الروبوت الخاص بي للرد على الرسائل ، ومع ذلك ، إذا حاولت تغيير وجود الروبوت ، يبدو الأمر كما لو أن جميع الرسائل التي ترسلها إلى الروبوت تتأخر.

ما أعنيه هو عندما أقوم بتشغيل البرنامج النصي ، أقوم بتغيير الوجود حتى أتمكن من رؤية أنه متصل بالإنترنت. ثم عندما أرسلها رسالة تستغرق ثلاثة قبل أن يتم استدعاء روتين رد الاتصال الذي قمت بإعداده للرسائل. بعد إرسال رسالة Thirrd ويتم تسمية روتين الدردشة ، لا يزال معالجة الرسالة الأولى التي أرسلتها.

هذا في الحقيقة لا يشكل الكثير من المشكلات باستثناء أنني قمت بإعداده لتسجيل الخروج عندما أرسل رسالة "تسجيل الخروج" ويجب أن تتبعها رسالتين أخريين لتسجيل الخروج. لست متأكدًا مما يجب أن أفعله لإصلاح هذا ، لكنني أعتقد أن الأمر يتعلق بحزم الذكاء لأن لدي مجموعة رد اتصال 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;
}

شكرا لمساعدتك!

هل كانت مفيدة؟

المحلول

لقد حصلت على جوع الموارد بسبب روتين Keepit. بشكل عام ، محاولة استخدام XMPP بشكل متزامن مثل هذا لن ينجح. أقترح إعداد عمليات الاسترجاعات الخاصة بك ، ثم مجرد استدعاء عملية () في واحد عقدة.

مستندات العملية () قل:

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 () قبل إرسال شيء ما ، فأنت دائمًا ما تفكر بشكل متزامن ، بدلاً من Asych ، الذي يقتلك في XMPP.

في حالتك ، إذا قمت بإزالة المكالمة للاحتفاظ بها من chat () ، أراهن أن الأمور ستعمل أكثر كما تتوقع.

نصائح أخرى

استبدل الخط:

$jabberBot->Process(1);

مع هذه:

while (defined($jabberBot->Process(1))) {
    # Do stuff here
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top