+ bless $connection, 'PingableConnection';
+ $connection->{'_pending_ping'} = undef;
+ $connection->{'_ping_sent'} = undef;
+ $connection->{'_stuck_timer'} = AnyEvent->timer(
+ after => 5.0,
+ interval => 5.0,
+ cb => sub {
+ if (defined($connection->{'_pending_ping'})) {
+ print STDERR "Timed out while waiting for pong on '$connection->{'_pending_ping'}'; disconnecting.\n";
+ $connection->close;
+ return;
+ }
+ chomp ($connection->{'_pending_ping'} = ctime(time));
+ $connection->{'_ping_sent'} = [Time::HiRes::gettimeofday];
+ $connection->ping($connection->{'_pending_ping'});
+ });
+ $connection->on_pong(sub {
+ my ($conn, $msg) = @_;
+ if (defined($connection->{'_pending_ping'}) && $connection->{'_pending_ping'} eq $msg->{'body'}) {
+ my $t0 = Time::HiRes::tv_interval($connection->{'_ping_sent'});
+ print STDERR "Received expected pong: $msg->{'body'} ($t0 seconds RTT)\n";
+ undef $connection->{'_pending_ping'};
+ undef $connection->{'_ping_sent'};
+ } else {
+ print STDERR "Received unexpected pong '$msg->{'body'}' (expected '$connection->{'_pending_ping'}'); disconnecting.\n";
+ $connection->close;
+ }
+ });
+
+