Data Channels

Rainway provides Peers with the ability to create Data Channels, over which they can exchange arbitrary application-level binary data.

The binary data format is up to your app. We like Bebop, our own lightning-fast schema-based binary serialization format — but UTF-8-encoded JSON is always an option, too.


Data Channels must be created using Runtime::createDataChannel(channelName, mode) by the Peer who initiated the connection. The Peer who accepted the connection will get onPeerDataChannel events for each opened channel.

From that point on, messages can then be sent using Peer::send(channelName, bytes). They are received as onPeerMessage events.

For more information on how to use Data Channels, see Exchanging Messages in your language-specific Getting Started guide.

Channel modes

A Data Channel can be created in one of two modes, specified by the mode parameter in createDataChannel.

In reliable mode, Rainway internally negotiates the retransmission of lost network packets, so that they always arrive, even if that means they arrive late or the network gets more congested. This mode is recommended in most situations.

In unreliable mode, lost packets are not retransmitted. This is recommended if the channel is used for frequent, ephemeral data where each update invalidates the previous one.


When sending a binary message longer than 16,000 bytes, Rainway automatically splits the message into chunks. It then automatically reassembles them on the receiving end before presenting the message to the remote app. This is mostly an implementation detail that you need not worry about. However, take note that in unreliable mode, if any of these chunks go missing, the entire message is discarded. Therefore, we don't recommend sending messages larger than about 500kB over an unreliable channel.

Requests and responses

Data Channels have a request method, which behaves like send, but waits asynchronously for a response.

When you call this method, the remote peer receives a message event with a respond method, which they can use to respond to your request.

In C++, request accepts a callback that will get called with the remote peer's response. In other languages, the return value of request is a Promise or Task that resolves to the remote peer's response.


The respond method on MessageEventRequest may not be called more than once.

If it is never called, the corresponding request promise never resolves.

Requests are not cancelable, and do not time out.