Argon

 view release on metacpan or  search on metacpan

lib/Argon/Client.pm  view on Meta::CPAN

);

has remote => (
  is  => 'rw',
  isa => 'Maybe[Str]',
);

has msg => (
  is      => 'rw',
  isa     => 'HashRef',
  default => sub {{}},
  traits  => ['Hash'],
  handles => {
    has_msg => 'exists',
    get_msg => 'get',
    add_msg => 'set',
    del_msg => 'delete',
    msg_ids => 'keys',
    msgs    => 'values',
  },
);

has channel => (
  is      => 'rw',
  isa     => 'Maybe[Argon::SecureChannel]',
  handles => [qw(send)],
);

has addr => (
  is      => 'ro',
  isa     => 'Str',
  lazy    => 1,
  builder => '_build_addr',
);

sub _build_addr {
  my $self = shift;
  join ':', $self->host, $self->port;
}


around BUILDARGS => sub {
  my $orig  = shift;
  my $class = shift;
  my %args  = @_;

  if (exists $args{channel}) {
    # Match encryption settings
    $args{$_} = $args{channel}{$_}
      foreach grep { exists $args{channel}{$_} }
        qw(key keyfile cipher token);
  }

  $class->$orig(%args);
};

sub BUILD {
  my ($self, $args) = @_;

  if ($self->channel) {
    # Set callbacks
    $self->channel->on_msg(K('_notify', $self));
    $self->channel->on_err(K('_error', $self));
    $self->channel->on_close(K('_close', $self));

    if ($self->channel->is_ready) {
      $self->opened->();
      $self->ready->();
    } else {
      $self->channel->on_ready(K('_ready', $self));
      $self->opened->();
    }
  }
  else {
    $self->connect;
  }
}

sub connect {
  my $self = shift;
  log_debug 'Connecting to %s', $self->addr;
  tcp_connect $self->host, $self->port, K('_connected', $self);
}

sub _connected {
  my ($self, $fh) = @_;

  if ($fh) {
    log_debug '[%s] Connection established', $self->addr;

    $self->channel(Argon::SecureChannel->new(
      fh       => $fh,
      key      => $self->key,
      token    => $self->token,
      remote   => $self->remote,
      on_msg   => K('_notify', $self),
      on_ready => K('_ready',  $self),
      on_err   => K('_error',  $self),
      on_close => K('_close',  $self),
    ));

    $self->opened->();
  }
  else {
    log_debug '[%s] Connection attempt failed: %s', $self->addr, $!;
    $self->cleanup;
    $self->failed->($!);
  }
}

sub reply_cb {
  my ($self, $msg, $cb, $retry) = @_;
  $self->add_msg($msg->id, {
    orig  => $msg,
    cb    => $cb,
    intvl => interval(1),
    retry => $retry,
  });
}




( run in 0.740 second using v1.01-cache-2.11-cpan-437f7b0c052 )