2012-09-04 54 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放在我的代码中。我应该做我自己的IO :: Socket连接,并以某种方式传递给Async :: Net :: WebSocket,但我无法做到这一点。其实我真的不知道我该怎么做。显然是初学者的问题。

我试着用定时器的第二种方法,它应该每30秒检查连接是否打开(如果没有新的数据通过套接字传入)。同样的问题,但来自另一方:不知道如何检查上述代码是否连接打开。

我可以做一个基本的IO :: Socket连接,但我想用上面的代码做点什么,因为我喜欢Net :: Async :: WebSocket如何通过事件(on_read-eof,on_frame等)来完成它。

回答

1

如何检查它是否仍然有效?

创建一个“心跳”。每隔一秒从客户端发送一个“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,