Asynchronous Socket
        
        
    What’s more asynchronous than socket communication? When two programs need to talk to
each other, often from different computers on different networks in different
parts of the world, you can connect using a socket. Whether an HTTP server or
some custom protocol, you can implement both sides of that communication using
IO::Socket::Async.
Let’s consider a simple calculator service. It listens for connections over TCP.
When a connection is established, it takes lines of input over the connection
and parses each line as a simple mathematic calculation like 2 + 2 or 6 * 7.
We can write the server like this.
react {
  whenever IO::Socket::Async.listen('127.0.0.1', 3456) -> $conn {
    whenever $conn.Supply.lines -> $line {
      if $line ~~ m:s/$<a> = [ \d+ ] $<op> = [ '+' | '-' | '*' | '/' ] $<b> = [ \d+ ]/ {
        my $a = +$<a>;
        my $b = +$<b>;
        my $r = do given "$<op>".trim {
          when '+' { $a + $b }
          when '-' { $a - $b }
          when '*' { $a * $b }
          when '/' { $a div $b }
          default { "Unknown Error"; }
        }
        $conn.print("$r\n");
      }
      else {
        $conn.print("Syntax Error\n");
      }
    }
  }
}
Now, the nested whenever block might look a little odd, but this is just fine.
You can add more whenever blocks within a react any time you need to this
way.
The outer whenever listens for new new connection objects. It’s sole job here
is to register the connection as another whenever block with the server. Be
aware that using this strategy does mean that you are handling all connections
asynchronously as if from a single thread. A more scalable solution might be to
use a start block for each arriving connection (which might look something like
this):
start react whenever $conn.Supply.lines -> $line { ... }
Moving on, the inner whenever then watches for lines of input from each
connection as it arrives.  It will receive a message whenever a line of input
has been sent by the client.  This code parses that line, performs the
expression (or discovers an error), and returns the result.
Simple.
We call listen to establish a listening TCP socket on the named address and
port number. This returns a Supply which
will emit connected IO::Socket::Async objects. You can use the Supply method
on the connection object to get text (or bytes via the :bin option), whenever
the are sent from the associated client. You use the write and print methods
to send bytes and text back.
The client can also be written with IO::Socket::Async as well. Here is a
client which uses our expression server to calculate the Fibonacci sequence:
my ($a, $b) = (0, 1);
say "$a";
say "$b";
await IO::Socket::Async.connect('127.0.0.1', 3456).then: -> $connection {
  given $connection.result -> $conn {
    $conn.print("$a + $b\n");
    react {
      whenever $conn.Supply.lines -> $line {
        $a = $b;
        $b = +$line;
        say "$b";
        $conn.print("$a + $b\n");
      }
    }
  }
}
When making a client conneciton, we use the connect method with IP address or
host name of the server to connect to. That method returns a
Promise which is kept once the
connection has been made. The result of that promise is a connected
IO::Socket::Async object which can be used in precisely the same way as the
server, with Supply returning text or bytes and write and print being used
to send text or bytes.
Cheers.