class IO::Socket::Async

Asynchronous socket in TCP or UDP
class IO::Socket::Async {}

IO::Socket::Async provides asynchronous sockets, for both the server and the client side.

Here is a simple example of a simple "hello world" HTTP server that listens on port 3333:

react {
    whenever IO::Socket::Async.listen('0.0.0.0', 8080) -> $conn {
        await $conn.print: qq:heredoc/END/;
            HTTP/1.1 200 OK
            Content-Type: text/html; charset=UTF-8
            Content-Encoding: UTF-8

            <html>
            <body>
                <h1>Incoming request:</h1>
            <pre>
            END
        whenever $conn.Supply.lines -> $line {
            $conn.say: $line;
            if $line ~~ "" {
                await $conn.print: "</pre></body></html>";
                $conn.close;
            }
            LAST { say "closed connection"; }
        }
    }
    CATCH {
        default {
            say .^name, ': ', .Str;
            say "handled in $?LINE";
        }
    }
}

And a client that connects to it, and prints out what the server answers:

await IO::Socket::Async.connect('127.0.0.1', 3333).then( -> $promise {
    given $promise.result {
        .print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n");
        react {
            whenever .Supply() -> $v {
                $v.print;
                done;
            }
        }
        .close;
    }
});

IO::Socket::Async can also send and receive UDP messages An example server that outputs all the data it receives would be:

my $socket = IO::Socket::Async.bind-udp('localhost', 3333);

react {
    whenever $socket.Supply -> $v {
        if $v.chars > 0 {
            say $v;
        }
    }
}

And an associated client might be:

my $socket = IO::Socket::Async.udp();
await $socket.print-to('localhost', 3333, "Hello, Raku!");

The CATCH phaser can be included to deal specifically with problems that might occur in this kind of sockets, such as a port being already taken:

react {
    whenever IO::Socket::Async.listen('0.0.0.0', 3000) -> $conn {
        whenever $conn.Supply.lines -> $line {
            $conn.print: qq:heredoc/END/;
                HTTP/1.1 200 OK
                Content-Type: text/html; charset=UTF-8
                Content-Encoding: UTF-8

                <html>
                <body>
                    <h1>Hello World!</h1>
                    <p>{ $line }</p>
                </body>
                </html>
                END
            $conn.close;
        }
        QUIT {
            default {
                say .^name, '→ ', .Str;
                say "handled in line $?LINE";
            }
        }
    }

}
# Will print this, if address 3000 is already in use:
# X::AdHoc→ address already in use
# handled in 23

Main difference with using other phasers such as CATCH is that this kind of exception will be caught within the whenever block and will put exiting the program, or not, under your control.

Methods

The IO::Socket::Async cannot be constructed directly, either connect or listen (for TCP connections) or udp or bind-udp (for UDP data) should be used to create a client or a server respectively.

method connect

method connect(Str $host, Int $port --> Promise)

Attempts to connect to the TCP server specified by $host and $port, returning a Promise that will either be kept with a connected IO::Socket::Async or broken if the connection cannot be made.

method connect-path

method connect-path(Str $path --> Promise)

Attempts to connect to a unix domain stream socket specified by $path, returning a Promise that will either be kept with a connected IO::Socket::Async or broken if the connection cannot be made.

method listen

method listen(Str $host, Int $port --> Supply)

Creates a listening socket on the specified $host and $port, returning a Supply to which the accepted client IO::Socket::Asyncs will be emitted. This Supply should be tapped start listening for client connections. You can set $port to 0 if you want the operating system to find one for you.

The IO::Socket::Async::ListenSocket returned by calling the tap method on the supply returned represents the underlying listening TCP socket, which can be closed using its close method. If $port was set to 0, you can get the port the socket ended up with using its socket-port method.

method listen-path

method listen-path(Str $path)

Creates a unix domain stream listening socket on the specified $path, returning a Supply to which the accepted client IO::Socket::Asyncs will be emitted. This Supply should be tapped start listening for client connections.

The IO::Socket::Async::ListenSocket returned by calling the tap method on the supply returned represents the underlying listening TCP socket, which can be closed using its close method.

method udp

method udp(IO::Socket::Async:U: :$broadcast --> IO::Socket::Async)

Returns an initialized IO::Socket::Async client object that is configured to send UDP messages using print-to or write-to. The :broadcast adverb will set the SO_BROADCAST option which will allow the socket to send packets to a broadcast address.

method bind-udp

method bind-udp(IO::Socket::Async:U: Str() $host, Int() $port, :$broadcast --> IO::Socket::Async)

This returns an initialized IO::Socket::Async server object that is configured to receive UDP messages sent to the specified $host and $port and is equivalent to listen for a TCP socket. The :broadcast adverb can be specified to allow the receipt of messages sent to the broadcast address.

method print

method print(IO::Socket::Async:D: Str $str --> Promise)

Attempt to send $str on the IO::Socket::Async that will have been obtained indirectly via connect or listen, returning a Promise that will be kept with the number of bytes sent or broken if there was an error sending.

method print-to

method print-to(IO::Socket::Async:D: Str() $host, Int() $port, Str() $str --> Promise)

This is the equivalent of print for UDP sockets that have been created with the udp method, it will try send a UDP message of $str to the specified $host and $port returning a Promise that will be kept when the data is successfully sent or broken if it was unable to send the data. In order to send to a broadcast address the :broadcast flag must have been specified when the socket was created.

method write

method write(IO::Socket::Async:D: Blob $b --> Promise)

This method will attempt to send the bytes in $b on the IO::Socket::Async that will have been obtained indirectly via connect or listen, returning a Promise that will be kept with the number of bytes sent or broken if there was an error sending.

method write-to

method write-to(IO::Socket::Async:D: Str() $host, Int() $port, Blob $b --> Promise)

This is the equivalent of write for UDP sockets that have been created with the udp method. It will try send a UDP message comprised of the bytes in the Blob $b to the specified $host and $port returning a Promise that will be kept when the data is successfully sent or broken if it was unable to send the data. In order to send to a broadcast address the :broadcast flag must have been specified when the socket was created.

method Supply

method Supply(:$bin, :$buf = buf8.new --> Supply)

Returns a Supply which can be tapped to obtain the data read from the connected IO::Socket::Async as it arrives. By default the data will be emitted as characters, but if the :bin adverb is provided a Buf of bytes will be emitted instead, optionally in this case you can provide your own Buf with the :buf named parameter.

A UDP socket in character mode will treat each packet as a complete message and decode it. In the event of a decoding error, the Supply will quit.

On the other hand, a TCP socket treats the incoming packets as part of a stream, and feeds the incoming bytes into a streaming decoder. It then emits whatever characters the decoder considers ready. Since strings work at grapheme level in Raku, this means that only known complete graphemes will be emitted. For example, if the UTF-8 encoding were being used and the last byte in the packet decoded to a, this would not be emitted since the next packet may include a combining character that should form a single grapheme together with the a. Control characters (such as \n) always serve as grapheme boundaries, so any text-based protocols that use newlines or null bytes as terminators will not need special consideration. A TCP socket will also quit upon a decoding error.

method close

method close(IO::Socket::Async:D: )

Close the connected client IO::Socket::Async which will have been obtained from the listen Supply or the connect Promise.

In order to close the underlying listening socket created by listen you can close the IO::Socket::Async::ListenSocket. See listen for examples.

method socket-host

method socket-host(--> Str)

Returns the IP address of the local end of this socket.

method peer-host

method peer-host(--> Str)

Returns the IP address of the remote end of this socket.

method socket-port

method socket-port(--> Int)

Returns the port of the local end of this socket.

method peer-port

method peer-port(--> Int)

Returns the port of the remote end of this socket.

method native-descriptor

method native-descriptor(--> Int)

Returns the file descriptor of this socket.

See Also

class Attribute

Member variable

class Cancellation

Removal of a task from a Scheduler before normal completion

class Channel

Thread-safe queue for sending values from producers to consumers

class CompUnit

CompUnit

class CompUnit::Repository::FileSystem

CompUnit::Repository::FileSystem

class CompUnit::Repository::Installation

CompUnit::Repository::Installation

class Distro

Distribution related information

class Grammar

Formal grammar made up of named regexes

class IO::ArgFiles

Iterate over contents of files specified on command line

class IO::CatHandle

Use multiple IO handles as if they were one

class IO::Handle

Opened file or stream

class IO::Notification

Asynchronous notification for file and directory changes

class IO::Notification::Change

Changes in a file, produced by watch-file

class IO::Path

File or directory path

class IO::Path::Cygwin

IO::Path pre-loaded with IO::Spec::Cygwin

class IO::Path::Parts

IO::Path parts encapsulation

class IO::Path::QNX

IO::Path pre-loaded with IO::Spec::QNX

class IO::Path::Unix

IO::Path pre-loaded with IO::Spec::Unix

class IO::Path::Win32

IO::Path pre-loaded with IO::Spec::Win32

class IO::Pipe

Buffered inter-process string or binary stream

class IO::Socket::Async::ListenSocket

A tap for listening TCP sockets

class IO::Socket::INET

TCP Socket

class IO::Spec

Platform specific operations on file and directory paths

class IO::Spec::Cygwin

Platform specific operations on file and directory paths for Cygwin

class IO::Spec::QNX

Platform specific operations on file and directory paths QNX

class IO::Spec::Unix

Platform specific operations on file and directory paths for POSIX

class IO::Spec::Win32

Platform specific operations on file and directory paths for Windows

class IO::Special

Path to special I/O device

class Kernel

Kernel related information

class Lock

A low-level, re-entrant, mutual exclusion lock

class Lock::ConditionVariable

Condition variables used in locks

class Match

Result of a successful regex match

class Pod::Block

Block in a Pod document

class Pod::Block::Code

Verbatim code block in a Pod document

class Pod::Block::Comment

Comment in a Pod document

class Pod::Block::Declarator

Declarator block in a Pod document

class Pod::Block::Named

Named block in a Pod document

class Pod::Block::Para

Paragraph in a Pod document

class Pod::Block::Table

Table in a Pod document

class Pod::Defn

Pod definition list

class Pod::FormattingCode

Pod formatting code

class Pod::Heading

Heading in a Pod document

class Pod::Item

Item in a Pod enumeration list

class Proc

Running process (filehandle-based interface)

class Proc::Async

Running process (asynchronous interface)

class Promise

Status/result of an asynchronous computation

class Regex

String pattern

class Semaphore

Control access to shared resources by multiple threads

class Supplier

Live Supply factory

class Supplier::Preserving

Cached live Supply factory

class Supply

Asynchronous data stream with multiple subscribers

class Tap

Subscription to a Supply

class Thread

Concurrent execution of code (low-level)

class ThreadPoolScheduler

Scheduler that distributes work among a pool of threads

class Unicode

Unicode related information

class VM

Raku Virtual Machine related information

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.