2012-09-04 3 views
3

저는 Perl 초보자이며 순간에 websockets와 싸우고 있습니다. 읽기, 시도 및 복사 - 붙여 넣기의 많은 후에 나는 일이 코드를 가지고 : 나는 한 가지 더 여기에서 필요로websocket에 대한 연결이 아직 Net :: Async :: WebSocket로 열리는 지 확인하십시오.

use strict; 
use warnings; 
use utf8; 
use Data::Dumper; 
use IO::Async::Loop; 
use IO::Async::Timer::Periodic; 
use Net::Async::WebSocket::Client; 
use Protocol::WebSocket::URL; 

my ($url, $msg, $last_update); 
$url = 'ws://127.0.0.1/stream'; 
$msg = 'get_lists'; 

my $uri = Protocol::WebSocket::URL->new->parse($url); 
my $loop = IO::Async::Loop->new; 
my $client = Net::Async::WebSocket::Client->new(
     on_frame => sub { 
       my ($self, $frame) = @_; 
       chomp($frame); 
       $last_update = time(); # use this in timer below 

       # do something else 
     } 
); 
$loop->add($client); 

$client->connect(
     host => $uri->host, 
     service => $uri->port, 
     url  => $url, 
     on_connected => sub { 
       warn "Connection established"; 

       if ($msg) { 
         $client->send_frame("$msg\n"); 
       } 
     }, 
     on_connect_error=> sub { die "CONNECT: ".Dumper \@_; }, 
     on_resolve_error=> sub { die "RESOLVE: ".Dumper \@_; }, 
     on_fail   => sub { die "FAIL: ".Dumper \@_; }, 
     on_read_eof  => sub { 
       $loop->remove($client); 

       # reconnect? 
     } 
); 

# is the connection to socket is still open? 
# check every 30 seconds if $last_update was not updated 
my $timer = IO::Async::Timer::Periodic->new(
     interval=> 30, 
     on_tick => sub { 
       if (!$last_update || time()-30 > $last_update) { 
         warn "Connection probably dead. No new data for 20 seconds."; 

         ## check connection 

         ## and reconnect if needed 
       } 
     }, 
); 
$timer->start; 
$loop->add($timer); 

$loop->loop_forever; 

을하고 나는이 해결하는 방법을 잘 모르겠습니다 : 내가 좋아하는 몇 가지 정보를 발견

https://stackoverflow.com/a/12091867/1645170하지만 내 코드에 SO_KEEPALIVE를 넣는 방법을 모르겠다. 아마 내 자신의 입출력 :: 소켓 연결을해야하고 어떻게 든 비동기 :: Net :: WebSocket에 전달하지만 그것을 할 수 없었다. 사실 나는이 일을 얼마나 크게 소리지를 생각이 없습니다. 분명히 초보자의 문제.

새 데이터가 소켓을 통해 들어오지 않으면 연결이 열려 있는지 여부를 30 초마다 확인해야하는 타이머로 두 번째 방법을 시도했습니다. 다시, 같은 문제가 있지만 다른 측면에서 : 연결이 열려 있는지 위의 코드로 확인하는 방법을 모르겠다.

기본 IO :: 소켓 연결을 만들 수 있지만 Net :: Async :: WebSocket이 이벤트 (on_read-eof, on_frame 등)를 사용하는 방식을 좋아하기 때문에 위의 코드로 어떻게 든하고 싶습니다.

답변

1

그래도 작동하는지 확인하는 방법?

"하트 비트"를 만드십시오. 클라이언트로부터 매 x 초마다 "ping"을 보내고 "pong"이 돌아올 때까지 기다리십시오. 타임 아웃에 도달하면 죽습니다.

서버에서 예제 중 하나에서 직접 소켓을 추가 할 수 있습니다.

도움이 될 경우 알려주십시오.

my $serversock = IO::Socket::INET->new(
    LocalHost => "127.0.0.1", 
    Listen => 1, 
) or die "Cannot allocate listening socket - [email protected]"; 

$serversock->setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1); 

my @serverframes; 

my $acceptedclient; 
my $server = Net::Async::WebSocket::Server->new(
    handle => $serversock,