APNS-Agent
view release on metacpan or search on metacpan
lib/APNS/Agent.pm view on Meta::CPAN
warnf "identifier:%s\tstate:%s\ttoken:%s", $d{identifier}, $d{state}, $d{token} || '';
}
},
disconnect_interval => sub { 60 },
send_interval => sub { 0.01 },
_sent_cache => sub { Cache::LRU->new(size => 10000) },
_queue => sub { [] },
__apns => '_build_apns',
_sent => sub { 0 },
},
rw => [qw/_last_sent_at _disconnect_timer/],
);
sub to_app {
my $self = shift;
my $router = Router::Boom::Method->new;
$router->add(POST => '/' => '_do_main');
$router->add(GET => '/monitor' => '_do_monitor');
sub {
lib/APNS/Agent.pm view on Meta::CPAN
sub _build_apns {
my $self = shift;
AnyEvent::APNS->new(
certificate => $self->certificate,
private_key => $self->private_key,
sandbox => $self->sandbox,
on_error => sub {
my ($handle, $fatal, $message) = @_;
my $t; $t = AnyEvent->timer(
after => 0,
interval => 10,
cb => sub {
undef $t;
infof "event:reconnect";
$self->_connect_to_apns;
},
);
warnf "event:error\tfatal:$fatal\tmessage:$message";
},
on_connect => sub {
infof "event:on_connect";
$self->_disconnect_timer($self->_build_disconnect_timer);
if (@{$self->_queue}) {
$self->_sending;
}
},
on_error_response => sub {
my ($identifier, $state) = @_;
my $data = $self->_sent_cache->get($identifier) || {};
$self->on_error_response->($self, {
identifier => $identifier,
lib/APNS/Agent.pm view on Meta::CPAN
sub _apns {
my $self = shift;
my $apns = $self->__apns;
$apns->connect unless $apns->connected;
$apns;
}
sub _connect_to_apns { goto \&_apns }
sub _build_disconnect_timer {
my $self = shift;
if (my $interval = $self->disconnect_interval) {
AnyEvent->timer(
after => $interval,
interval => $interval,
cb => sub {
if ($self->{__apns} && (time - ($self->_last_sent_at || 0) > $interval)) {
delete $self->{__apns};
delete $self->{_disconnect_timer};
infof "event:close apns";
}
},
);
}
else { undef }
}
sub _sending {
my $self = shift;
$self->{_send_timer} ||= AnyEvent->timer(
after => $self->send_interval,
interval => $self->send_interval,
cb => sub {
my $msg = shift @{ $self->_queue };
if ($msg) {
$self->_send(@$msg);
}
else {
delete $self->{_send_timer};
}
},
);
}
sub _send {
my ($self, $token, $payload) = @_;
local $@;
my $identifier;
eval {
$identifier = $self->_apns->send(pack("H*", $token) => {
aps => $payload,
});
};
if (my $err = $@) {
if ($err =~ m!Can't call method "push_write" on an undefined value!) {
# AnyEvent::APNS->handle is missing
delete $self->{_send_timer};
unshift @{ $self->_queue }, [$token, $payload];
$self->_connect_to_apns;
}
else {
die $err;
}
}
else {
$self->_sent_cache->set($identifier => {
token => $token,
( run in 0.458 second using v1.01-cache-2.11-cpan-49f99fa48dc )