AsyncSocket

Proactor-model inspired asynchronous socket implementation. In contrast to POSIX.1-2013 readiness I/O - which essentially describes synchronous socket I/O operations with asynchronous notification of future blocking behaviour for said operations - this provides an API for asynchronous socket I/O operations: The three major socket operations accept, receive, and send modeled by this API will submit a request for asynchronous completion; towards that end, each call to these must be provided with a callback that will be called to notify you of said competion. It is therefore not recommended to keep calling any of these three methods in rapid succession, as they will normally not fail (bugs, memory exhaustion, or the operating system not supporting further pending requests excluded) to notify you that you should try again later. They will, however, notify you via the callbacks you provide once a request has been completed, or once there has been a socket error (refer to OnError). It follows that you should usually have only a small number of requests pending on a socket at the same time (preferably at most only a single receive and a single send - respectively a single accept) and submit the next request only once the previous one (of the same type) notifies you of its completion. For connection-oriented, active sockets, connection completion and disconnect (by the remote peer) are handled by OnConnect and OnClose respectively; disconnecting from the remote peer can be initiated with kill and will not trigger OnClose.

final
class AsyncSocket {}

Constructors

this
this(EventLoop evLoop, int domain, SocketType type, int protocol, fd_t handle)

Create a new asynchronous socket within domain of type using protocol from an existing OS handle. It is your responsibility to ensure that handle - in addition to being a valid socket descriptor - fulfills all requirements to be used by AsyncSocket: POSIX: Must be non-blocking (keyword O_NONBLOCK) Windows: Must be overlapped (keyword WSA_FLAG_OVERLAPPED)

this
this(EventLoop evLoop, int domain, SocketType type, int protocol)

Create a new asynchronous socket within domain of type using protocol.

this
this(EventLoop eventLoop, int domain, SocketType type)

Convenience constructor for when there is only one protocol supporting both domain and type.

this
this(EventLoop evLoop, int domain, int type, int protocol)

Convenience constructor if avoiding SocketType is preferred. Supports only SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM, SOCK_RAW, and SOCK_RDM.

this
this(EventLoop evLoop, int domain, int type)

Convenience constructor for when there is only one protocol supporting both domain and type.

Destructor

A destructor is present on this object, but not explicitly documented in the source.

Members

Aliases

OnClose
alias OnClose = void delegate()

Type of callback triggered when a connection-oriented, active socket completes disconnects. The socket will have been killed before the call.

OnConnect
alias OnConnect = void delegate()

Type of callback triggered when a connection-oriented socket completes connecting

OnError
alias OnError = void delegate()

Type of callback triggered when a socker error occured. The socket will have been killed before the call.

Functions

accept
void accept(AsyncAcceptRequest.OnComplete onAccept)

Submits an asynchronous request on this socket to accept an incoming connection. Upon successful acceptance of such a connection onAccept will be called with a new AsyncSocket representing the peer.

bind
bool bind(sockaddr* addr, socklen_t addrlen)

Assigns the network address pointed to by addr, with addrlen specifying the size, in bytes, of this address, as the local name of this socket.

bind
bool bind(const ref NetworkAddress addr)

Convenience wrapper.

connect
bool connect(sockaddr* addr, socklen_t addrlen)

Assigns the network address pointed to by addr, with addrlen specifying the size, n bytes, of this address, as the name of the remote socket. For connection-oriented sockets, also start establishing a connection with that socket and call onConnect once it has.

connect
bool connect(const ref NetworkAddress to)

Convenience wrapper.

getOption
int getOption(int level, int option, void[] result)

Get a socket option (taken from std.socket).

getOption
int getOption(int level, int option, out int result)

Common case of getting integer and boolean options (taken from std.socket).

kill
bool kill(bool forced = false)

Removes the socket from the event loop, shutting it down if necessary, and cleans up the underlying resources. Only after this method has been called may the socket instance be deallocated.

listen
bool listen(int backlog = SOMAXCONN)

Marks the socket as passive and enables acceptance of incoming connections into instances of AsyncSocket. Only after calling this successfully may accept request be submitted via accept.

receive
void receive(ref ubyte[] data, AsyncReceiveRequest.OnDataReceived onReceive)

Submits an asynchronous request on this socket to receive data. Upon successful reception of at most data.length bytes onReceive will be called with the received bytes as a slice of data.

receive
void receive(AsyncReceiveRequest.OnDataAvailable onReceive)

Submits a special asynchronous request on this socket to receive nothing. Also known as a "zero byte receive" onReceive will be called once there is new data on the socket that can be received immediately. Additionally, onReceive may also be called on connection-oriented sockets where the remote peer has disconnected gracefully with no further data being available for reception.

receiveExactly
void receiveExactly(ref ubyte[] data, AsyncReceiveRequest.OnDataReceived onReceive)

Submits an asynchronous request on this socket to receive data. Upon successful reception of exactly data.lengt bytes onReceive will be called with data.

receiveFrom
void receiveFrom(ref ubyte[] data, ref NetworkAddress from, AsyncReceiveRequest.OnDataReceived onReceive)

Submits an asynchronous request on this socket to receive data from an unknown sender, whose address will also be received. Upon successful reception of at most data.length bytes onReceive will be called with the received bytes as a slice of data and from will have been set to the sender's address. This method may only be called on connectionless sockets, to retrieve the remote address on connection-oriented sockets, refer to remoteAddress.

receiveMessage
void receiveMessage(NetworkMessage* message, AsyncReceiveRequest.OnComplete onReceive, bool exact)

Submits an asynchronous request on this socket to receive a message. Upon successful reception onReceive will be called with the received data. exact indicates whether successful reception requires the entire buffer provided within message to have been filled. If a socket error occurs, but some data has already been received, then onReceive will be called with that partial data regardless of exact. The message must have been allocated using NetworkMessage.alloc and will be freed with NetworkMessage.free after the completion callback returns, or once an error occurs that prevents said callback from being called.

receiveMessage
void receiveMessage(ref NetworkMessage message, AsyncReceiveRequest.OnDataReceived onReceive, bool exact = false)

Submits an asynchronous request on this socket to receive a message. Upon successful reception onReceive will be called with the received data. exact indicates whether successful reception requires the entire buffer provided within message to have been filled. If a socket error occurs, but some data has already been received, then onReceive will be called with that partial data regardless of exact.

resetHandle
fd_t resetHandle()

Reset internal OS socket handle to INVALID_SOCKET and return its previous value

run
bool run()

Creates the underlying OS socket - if necessary - and registers the event handler in the underlying OS event loop.

send
void send(in ubyte[] data, AsyncSendRequest.OnComplete onSend)

Submits an asynchronous request on this socket to send data. Upon successful transmission onSend will be called.

sendMessage
void sendMessage(NetworkMessage* message, AsyncSendRequest.OnComplete onSend)

Submits an asynchronous request on this socket to send a message. Upon successful transmission onSend will be called. The message must have been allocated using NetworkMessage.alloc and will be freed with NetworkMessage.free after the completion callback returns, or once an error occurs that prevents said callback from being called.

sendMessage
void sendMessage(const ref NetworkMessage message, AsyncSendRequest.OnComplete onSend)

Submits an asynchronous request on this socket to send a message. Upon successful transmission onSend will be called.

sendTo
void sendTo(in ubyte[] data, const ref NetworkAddress to, AsyncSendRequest.OnComplete onSend)

Submits an asynchronous request on this socket to send data to a specific recipient. Upon successful transmission onSend will be called.

setOption
void setOption(int level, int option, void[] value)

Set a socket option (taken from std.socket).

setOption
void setOption(int level, int option, int value)

Common case for setting integer and boolean options (taken from std.socket).

Mixins

__anonymous
mixin DefStatus

Provides access to event loop information

Properties

alive
bool alive [@property getter]

Returns whether the socket has not yet been killed.

connectionOriented
bool connectionOriented [@property setter]
connectionOriented
bool connectionOriented [@property getter]

Whether this socket establishes a (stateful) connection to a remote peer.

datagramOriented
bool datagramOriented [@property getter]

Whether this socket transceives datagrams.

handle
fd_t handle [@property getter]

The underlying OS socket descriptor

info
SocketInfo info [@property getter]
lastError
auto lastError [@property getter]

Retrieves and clears the most recent error on this socket

localAddress
NetworkAddress localAddress [@property getter]
onClose
OnClose onClose [@property setter]

Sets this socket's OnClose callback.

onConnect
OnConnect onConnect [@property setter]

Sets this socket's OnConnect callback.

onError
OnError onError [@property setter]

Sets callback for when a socket error has occurred.

passive
bool passive [@property getter]

Whether this socket has been put into passive mode.

receiveContinuously
bool receiveContinuously [@property getter]

Whether the socket is automatically resubmitting the current receive request upon its successful completion.

receiveContinuously
bool receiveContinuously [@property setter]

Toggles automatic resubmission of the current receive request upon its successful completion. Enabling this primes the socket so that the next receiveMessage will exhibit the behaviour. Any further calls to receiveMessage while active are forbidden; may only be disabled again in the completion callback provided with the receiveMessage that started it. After disabling, may not be reenabled in the same callback.

remoteAddress
NetworkAddress remoteAddress [@property getter]

Variables

m_evLoop
EventLoop m_evLoop;

Event loop of the thread this socket was created on.

m_pendingAccepts
AsyncAcceptRequest.Queue m_pendingAccepts;

Queue of calls to accept.

m_pendingReceives
AsyncReceiveRequest.Queue m_pendingReceives;

Queue of calls to receiveMessage.

m_pendingSends
AsyncSendRequest.Queue m_pendingSends;

Queue of requests initiated by sendMessage.

Meta

Authors

Moritz Maxeiner, moritz@ucworks.org

Date

Date: 2016