Length-prefix Framing experimental

Length-prefix framing is a simple protocol for encoding variable-length messages on the network. Each message is preceded by a fixed-length value (32 bit) that indicates the length of the message in bytes.

When a sender wants to transmit a message, it first encodes the message into a sequence of bytes. It then calculates the length of the byte sequence and prefixes the message with the length. The receiver then reads the length prefix to determine the length of the message before reading the bytes for the message.

Note

For the high-level API, include caf/net/lp/with.hpp.

Servers

The simplest way to start a length-prefix framing server is by using the high-level factory DSL. The entry point for this API is calling the caf::net::lp::with function:

caf::net::lp::with(sys)

Optionally, you can also provide a custom trait type by calling caf::net::lp::with<my_trait>(sys) instead. The default trait class caf::net::lp::default_trait configures the transport to exchange caf::net::lp::frame objects with the application, which essentially wraps raw bytes.

Once you have set up the factory, you can call the accept function on it to start accepting incoming connections. The accept function has multiple overloads:

  • accept(uint16_t port, std::string bind_address = "") for opening a new port. The bind_address optionally restricts which IP addresses may connect to the server. Passing an empty string (default) allows any client.

  • accept(tcp_accept_socket fd) for running the server on already configured TCP server socket.

  • accept(ssl::tcp_acceptor acc) for running the server on already configured TCP server socket with an SSL context. Using this overload after configuring an SSL context is an error, since CAF cannot use two SSL contexts on one server.

After setting up the factory and calling accept, you can use the following functions on the returned object:

  • do_on_error(F callback) installs a callback function that CAF calls if an error occurs while starting the server.

  • max_connections(size_t value) configures how many clients the server may allow to connect before blocking further connections attempts.

  • reuse_address(bool value) configures whether we create the server socket with SO_REUSEADDR. Has no effect if we have passed a socket or SSL acceptor to accept.

  • start(OnStart) to initialize the server and run it in the background. The OnStart callback takes an argument of type trait::acceptor_resource. This is a consumer resource for receiving accept events. Each accept event consists of an input resource and an output resource for reading from and writing to the new connection.

After calling start, CAF returns an expected<disposble>. On success, the disposable is a handle to the launched server and calling dispose on it stops the server. On error, the result contains a human-readable description of what went wrong.

Clients

Starting a client also uses the with factory. Calling connect instead of accept creates a factory for clients. The connect function may be called with:

  • connect(std::string host, uint16_t port) for connecting to the server at host on the given port.

  • connect(stream_socket fd) for establishing a WebSocket connection on an already connected TCP socket.

  • connect(ssl::tcp_acceptor acc) for establishing a WebSocket connection on an already established SSL connection.

After calling connect, we can configure various parameters:

  • do_on_error(F callback) installs a callback function that CAF calls if an error occurs while starting the server.

  • retry_delay(timespan) to set the delay between connection retries when a connection attempt fails.

  • connection_timeout(timespan) to set the maximum amount of time to wait for a connection attempt to succeed before giving up.

  • max_retry_count(size_t) to set the maximum number of times to retry a connection attempt before giving up.

Finally, we call start to launch the client. The function expects an OnStart callback takes two arguments: the input resource and the output resource for reading from and writing to the new connection.