2013-10-10 1 views
1

필자는 사용되지 않고 문서화되지 않은 Net :: IRC 라이브러리를 사용하여 Perl로 작성된 IRC 봇을 보유하고 있습니다. 그래도 연결이 끊어지지 않는 한 정상적으로 작동합니다. 다시 연결 지원을 구현하기 전에 라이브러리의 업데이트가 중단 된 것 같습니다. 분명한 해결책은 도서관의 후계자를 사용하기 위해 전체 로봇을 다시 작성하는 것이지만, 불행히도 전체 로봇을 다시 작성해야합니다.Net :: IRC 봇에 인터넷 연결 탐지기를 설치하는 방법은 무엇입니까?

해결 방법에 관심이 있습니다.

현재 설정은 프로세스가 예기치 않게 종료 될 때마다 봇을 다시 시작하도록 구성된 슈퍼 바이저이며 인터넷 연결이 끊어 질 때마다 프로세스를 종료하는 cron 작업입니다.

봇이 인터넷 중단으로 인해 연결이 끊어 졌음을 감지 할 수 없기 때문에이 기능이 제대로 작동하지 않습니다. IRC 서버에 계속 연결되어있는 것처럼 보이지만 아무것도하지 않고 행복하게 계속 실행됩니다.

나는 메인 프로그램 루프로 다음과 같은 코드가 있습니다

while (1) { 
    $irc->do_one_loop; 
    # can add stuff here 
} 

내가 그것을 할 싶은 무엇이다 :
이)가 될 때까지 기다려야)
B, 인터넷이 추락했습니다 감지 인터넷이 올라갔습니다.
c) 감독자가 스크립트를 종료 할 수 있도록 스크립트를 종료하십시오.

더 좋은 방법이 있습니까?

편집 : 알 수없는 이유로 스크립트 내 방법이 작동하지 않았습니다. 나는 그것을 해결하기 위해 별도의 스크립트를 만들려고 노력하고있다. do_one_loop, 당신은 적극적으로 네트워크가 있는지 여부를 알 수있는 무언가를 폴링해야합니다 (그것은 않는 경우 일부 alarm을 추가해야 할 수 있습니다) 끊지 것을 가정

#!/usr/bin/perl 

use Net::Ping::External; 

while (1) { 
    while (Net::Ping::External::ping(host => "8.8.8.8")) { sleep 5; } 

    sleep 5 until Net::Ping::External::ping(host => "8.8.8.8"); 
    system("sudo kill `pgrep -f 'perl painbot.pl'`"); 
} 

답변

1

. 이 같은 것은 응답이 발생할 때까지 5 초마다 ping을 수행 한 다음 종료해야합니다.

use Net::Ping::External; 
sub connectionCheck { 
    return if Net::Ping::External::ping(host => "8.8.8.8"); 

    sleep 5 until Net::Ping::External::ping(host => "8.8.8.8"); 
    exit; 
} 

편집 : do_one_loop 이후 가 응답하지 보인다, 당신은 주위에 시간 제한을 포장 할 수있는 방법이 필요합니다. 시간은 예상되는 시간과 응답하지 않을 때까지 기다리는 기간에 따라 다릅니다. 이 작업을 수행하는 간단한 방법은 (당신이 창에없는 가정) alarm을 사용하고 있습니다 :

local $SIG{'ALRM'} = sub { die "Timeout" }; 
alarm 30; # 30 seconds 
eval { 
    $irc->do_one_loop; 
    alarm 0; 
}; 
+0

그것은 그 do_one_loop이 달려 보인다 :

는 다음과 같이 (내가 그것을 테스트하지 않았습니다, 그리고 마지막으로 모듈을 사용 이후 7 년 됐어을 ...) 시도 알람 '그것을 풀다? 내 기능 중 하나가 아니라 도서관에서 가져온 것입니다. –

+0

나는 이것을 시도했는데, http://pastie.org/8396134처럼 그렇게하지 않았다. 아마 별도의 스크립트에 넣을 수 있는데, 대신 시스템 호출을 통해 로봇을 죽일 수 있습니까? –

+0

계획과 같은 소리 – AKHolland

1

Net::IRC 메인 루프는 시간 제한 및 예약 이벤트에 대한 지원을하고있다. - 나는`어떻게 사용합니까

# connect to IRC, add event handlers, etc. 
$time_of_last_ping = $time_of_last_pong = time; 
$irc->timeout(30); 
# Can't handle PONG in Net::IRC (!), so handle "No origin specified" error 
# (this may not work for you; you may rather do this some other way) 
$conn->add_handler(409, sub { $time_of_last_pong = time }); 
while (1) { 
    $irc->do_one_loop; 
    # check internet connection: send PING to server 
    if (time-$time_of_last_ping > 30) { 
     $conn->sl("PING"); # Should be "PING anything" 
     $time_of_last_ping = time; 
    } 
    break if time-$time_of_last_pong > 90; 
} 
+0

왜 저에게 효과가 없을까요? –