AnyEvent-APNS

 view release on metacpan or  search on metacpan

lib/AnyEvent/APNS.pm  view on Meta::CPAN


    if ($self->is_debug) {
        $host = '127.0.0.1';
        $port = $self->debug_port;
    }
    my $g = tcp_connect $host, $port, sub {
        my ($fh) = @_
            or return $self->on_error->(undef, 1, $!);

        my $tls_setting = {};
        if (ref $self->certificate) {
            $tls_setting->{cert}      = ${ $self->certificate };
        }
        else {
            $tls_setting->{cert_file} = $self->certificate;
        }

        if (ref $self->private_key) {
            $tls_setting->{key}       = ${ $self->private_key };
        }
        else {
            $tls_setting->{key_file}  = $self->private_key;
        }

        my $handle = AnyEvent::Handle->new(
            fh       => $fh,
            on_error => sub {
                $self->on_error->(@_);
                $self->clear_handler;
                $_[0]->destroy;
            },
            !$self->is_debug ? (
                tls      => 'connect',
                tls_ctx  => $tls_setting,
            ) : (),
        );
        $self->handler( $handle );

        if ($self->on_eof) {
            $handle->on_eof(sub {
                $self->on_eof->(@_);
                $self->clear_handler;
                $_[0]->destroy;
            });
        }

        if ( $self->on_error_response ) {
            $handle->on_read(
                sub {
                    $self->_on_read_with_error_callback( @_ );
                }
            );
        }
        else {
            $handle->on_read( sub { delete $_[0]->{rbuf} } );
        }

        $self->on_connect->();
    };

    Scalar::Util::weaken($self);
    $self->_con_guard($g);

    $self;
}

sub _on_read_with_error_callback {
    my ($self, $handle) = @_;
    $handle->push_read( chunk => 1,
                        sub {
                            my $command = unpack( 'C', $_[1] );
                            if ( $command != 8 ) {
                                # something is wrong
                                # auto reconnect
                                $self->clear_handler;
                                $self->connect;
                            }
                        });
    $handle->push_read( chunk => 5,
                        sub {
                            my $status     = unpack( 'C', substr( $_[1], 0, 1) );
                            my $identifier = unpack( 'N', substr( $_[1], 1, 4) );
                            $self->on_error_response->( $identifier => $status );
                        });
}

# 0 ... 2**32-1, 0 ... 2**32-1, 0 ...
sub _increment_identifier {
    my ($self) = @_;
    my $next_identifier = $self->last_identifier + 1;
    if ( $next_identifier >= 2 ** 32 ) {
        # identifier is only 4 bytes
        $next_identifier = 0;
    }
    $self->last_identifier( $next_identifier );
}

__PACKAGE__->meta->make_immutable;

__END__

=for stopwords
apns SDK TODO iPhone multi-byte utf8

=head1 NAME

AnyEvent::APNS - Simple wrapper for Apple Push Notifications Service (APNS) provider

=head1 SYNOPSIS

    use AnyEvent::APNS;

    my $cv = AnyEvent->condvar;

    my $apns; $apns = AnyEvent::APNS->new(
        certificate => 'your apns certificate file',
        private_key => 'your apns private key file',
        sandbox     => 1,
        on_error    => sub { # something went wrong },
        on_connect  => sub {
            my $identifier = $apns->send( $device_token => {



( run in 2.012 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )