2010-03-29 2 views
0

내 Jabber 봇을 만들려고하고 있지만 약간 문제가 있습니다. 내 봇이 메시지에 응답하도록했습니다. 그러나 봇의 존재를 변경하려고하면 봇에 보내는 모든 메시지가 지연되는 것처럼 보입니다.로그 아웃하기 전에 왜 Jabber 봇에 여러 개의 메시지를 보내야합니까?

내가 말하는 것은 온라인 상태임을 알 수 있도록 스크립트를 실행할 때 현재 상태를 변경하는 것입니다. 그런 다음 메시지를 보내면 콜백 서브 루틴 전에 메시지가 셋업되기 전에 세 번 걸립니다. thirrd 메시지가 전송되고 채팅 서브 루틴이 호출 된 후에도 보내진 첫 번째 메시지가 여전히 처리됩니다.

이것은 "logout"메시지를 보낼 때 로그 아웃하도록 설정 한 것을 제외하고는 너무 많은 문제를 일으키지 않으며 로그 아웃하기 위해 두 개의 메시지가 계속되어야합니다. 나는 이것이 무엇인지를 고쳐야 만하는지 확신 할 수 없다.하지만 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 @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; 
} 

감사 :

여기 내 소스 코드입니다!

+0

내가 문제가 제목이 질문과 관련이있다 알아내는 데 문제 – mob

+0

XMPP 모듈을 사용하는 방법을 perl과 함께 사용하는 방법을 모르겠습니다. 위에서 말했듯이 메시지를 처리하는 메시지가 대기열에 들어간 것처럼 보입니다. 이론적으로 메시지 # 3을 처리해야 할 때 메시지 # 1을 처리하고 # 4를 처리해야 할 때 메시지 # 2를 처리해야합니다. 등 – cskwrd

+0

좋아,이 작업에 XMPP와 Perl을 사용하고 있습니다. 그러나 귀하의 메시지는 XMPP와 Perl이 문제임을 입증하지 못합니다. Net :: Jabber를 사용하는 방식 때문일 수 있습니다. 어쩌면 그것은 버퍼링 된 양말 또는 얇은 판 줄 또는 100 개의 다른 것들과 관련이있을 것입니다. 누군가는 "어떻게 XMPP 모듈이 perl에서 작동하는지"(다른 모든 모듈이 perl에서 작동하는 것과는 대조적으로) 당신에게 설명 할 수는 있지만 문제 해결에 더 가까이 다가 갈 수 있다는 것은 분명하지 않습니다. Jabber가 응답하기 전에 "내 메시지를 세 번 보내야하는 이유는 무엇입니까?" – mob

답변

0

keepItGoing 루틴으로 인해 리소스 부족이 발생했습니다. 일반적으로 이와 같이 XMPP를 동 기적으로 사용하려고하면 작동하지 않습니다. 콜백을 설정 한 다음 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. 

때마다 당신은(), 당신의 콜백의 0 이상이 발생합니다 프로세스를 호출합니다. 서버 타이밍에 달려 있기 때문에 어느 것을 모를 수 있습니다. 뭔가를 보내기 전에 Process()가 반환되기를 원한다면, XMPP에서 당신을 죽이는 asych가 아닌, 항상 동기식으로 생각하고 있습니다.

귀하의 경우, keepItGoing에 대한 호출을 chat()에서 제거하면 기대했던 것보다 더 효과적 일 수 있습니다. 이들과

$jabberBot->Process(1); 

:

while (defined($jabberBot->Process(1))) { 
    # Do stuff here 
} 
+0

@ Joe Hildebrand : 당신이 말하는 것과 비슷한 예를 들어 줄 수 있습니까? 솔루션을 시각화하는 데 문제가 있습니다. 감사! – cskwrd

+0

@Joe Hildebrand :'chat()'에서'keepItGoing'을 제거하면 "logout?"과 같은 메시지를 보내기 전까지 스크립트를 계속 실행하려면 어떻게해야합니까? 나는 봇을 "유휴 상태로 만드는"방법에 대해 혼란 스럽다. 나는'keepItGoing' 서브 루틴으로 내가 이뤄낸 것이라고 생각했다. 제안을 구현 한 후 스크립트가 종료되므로 내 봇은 결국 서버와의 연결을 끊습니다. – cskwrd

0

라인을 교체합니다.
관련 문제