對於我來說,我似乎無法弄清楚如何獲得一個標準的TCP套接字連接後重新連接斷開,尤其是在IO ::異步::環Perl IO :: Socket :: INET + IO :: Async :: Stream在斷開連接時重新連接到TCP服務器
一些基本的方面:
#!/usr/bin/perl
use strict;
use warnings;
use Socket;
use IO::Async::Loop;
use IO::Async::Stream;
use IO::Socket;
use Time::HiRes qw(usleep);
# standard event loop
my $loop = IO::Async::Loop->new;
# notification service socket connection; we only write outgoing
my $NOTIFY = IO::Socket::INET->new(
PeerHost => $a_local_network_host,
PeerPort => $comm_port,
Proto => 'tcp',
Type => SOCK_STREAM,
ReuseAddr => 1,
Blocking => 0
) or warn("Can't connect to NOTIFY: $!\n");
setsockopt($NOTIFY, SOL_SOCKET, SO_KEEPALIVE, 1);
# main interface element via IO::Async
my $notifystream = IO::Async::Stream->new(
handle => $NOTIFY,
on_read => sub {
my ($self, $buffref, $eof) = @_;
# here's where we need to handle $eof if the remote goes away
if($eof) {
# i have tried several things here
usleep(200000); # give the remote service some milliseconds to start back up
# process fails if remote is not back up, so i know the timeout is 'good enough' for this test
# attempt to reconnect. have also tried recreating from scratch
$NOTIFY->connect("$a_local_network_host:$comm_port");
# this doesn't seem to have any effect
$self->configure(handle=>$NOTIFY);
}
}
);
$loop->add($notifystream);
# kickstart the event loop
$loop->run;
### -- Meanwhile, elsewhere in the code -- ###
$notifystream->write("data for notification service\n");
在現實中,有很多事情在循環回事。我還有更復雜的方法來測試socket關閉或中斷,$ notifystream上的更多錯誤處理程序,以及重新連接到遠程服務的更好的超時/退避,但是這應該顯示我正在做的主要關鍵。
當遠程服務器由於任何原因而離開時,我想嘗試重新連接它而不會中斷系統的其他部分。在大多數情況下,遠程發送eof乾淨,因爲它有意重新啓動(不是我的選擇,只是我必須處理),但我也想處理其他通信錯誤。
在實踐中,上述代碼的工作方式就像它的工作原理一樣,但遠程服務不再接收對$ notifystream的進一步寫入調用。沒有錯誤產生,$ notifystream愉快地進一步寫入,但他們不被傳送到遠程。
我有一種感覺,我做錯了。我不打算重寫應用程序事件循環的其餘部分,所以請不要'只使用AnyEvent'類型的響應 - 真正希望更好地瞭解如何重新連接/重用/重新創建使用的變量(IO :: Socket :: INET和IO :: Async :: Stream)來補償遠程服務器暫時不可用時的情況。
歡迎對此目標提出任何建議或參考。謝謝!
- = - = - = - = -
總結錯誤我有(並且沒有)接收: 如果我不留usleep,基座插座由於將失敗的重新連接(或娛樂)遠程服務不可用。 如果我試圖從頭開始重新創建套接字,然後'配置'流,我得到'不能調用未定義的方法sysread這導致我相信套接字沒有正確重新創建。 在任何時候,無論我使用當前代碼寫入套接字的時間多少,流的內置'on_read_error'或'on_write_error'處理程序都會觸發,但如果我完全銷燬套接字,則會生成一個錯誤。 套接字似乎仍然是活躍的,我知道它已經關閉,重新連接似乎並沒有改變任何東西。沒有錯誤產生,但套接字沒有被寫入。
是否有不同的語法重新連接到一個IO ::套接字:: INET套接字?到目前爲止,調用connect()或重新開始重建似乎是關閉連接的唯一選項,並且都不起作用。
我沒有看到任何錯誤檢查?你提到你有他們,他們說什麼?你肯定需要「重新啓用」重新啓動,這些錯誤將有助於弄清楚什麼。 – zdim
我在IO :: Async :: Stream中有'on_read_error','on_write_error'和'on_writeable_stop' - 它們都沒有觸發。在所有。我也試過/ catch'd所有 - 問題是沒有引發錯誤。它只是不起作用。 – derelict
你嘗試重新連接你的'$ NOTIFY'嗎?這個問題還不清楚。你可能也可能不需要再向環路添加'(也許重新啓動它)。你能澄清你是否嘗試過,你能否用這些錯誤檢查方法所說的信息來完成這個問題? – zdim