use 5.12.0; use warnings; use UniEvent; use Net::SSLeay; # This is async echo client. Comparing to "simple" client, it is almost # completely non-blocking, as it reads in non-blocking mode from console # and write and reads non-blocking mode over TCP/SSL stream. # The "almost" means, that output to console (i.e. "say" instructions) # can still block. "say" is used for simplicity. # To launch echo client in ssl mode executed something like # perl examples/echo-client-simple.plx 1234 examples/ca.pem my ($port, $ca) = @ARGV; $port //= 9999; my $client = UniEvent::Tcp->new; if ($ca) { my $client_ctx = Net::SSLeay::CTX_new(); my $ssl_err = sub { die Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error); }; Net::SSLeay::CTX_load_verify_locations($client_ctx, $ca, '') or $ssl_err->(); $client->use_ssl($client_ctx); } my $loop = UniEvent::Loop->default_loop; say "connecting to $port ..."; $client->connect('127.0.0.1', $port, sub { my ($client, $error_code) = @_; # will be thrown out of loop run die("cannot connect: $error_code\n") if $error_code; $loop->stop; }); $loop->run; say "connected"; $client->read_callback(sub { my ($client, $data, $error_code) = @_; die("reading data error: $error_code\n") if $error_code; say "[<<] ", $data; }); $client->eof_callback(sub { say "[eof,remote]"; $loop->stop; }); my $tty_in = UniEvent::Tty->new(\*STDIN, $loop); $tty_in->read_start(); my $line = ''; $tty_in->read_callback(sub { my ($tty_in, $data, $error_code) = @_; die("reading data error: $error_code\n") if $error_code; $line .= $data; return unless $line =~ s/((.+)\n)//; my $out = $1; chomp($out); $client->write($out, sub { my ($client, $error_code) = @_; die("writing data error: $error_code\n") if $error_code; say "[>>] ", $out; }) }); $tty_in->eof_callback(sub { say "[eof,tty]"; $loop->stop; }); $loop->run; say "normal exit";