Messages, Channels and Reliability¶
Payloads¶
A message is a sequence of bytes. EnetPeer.send() takes bytes;
EnetPeer.send_datagram() takes a Datagram and sends its
contents. On the receiving side EnetEvent.data is the payload as
bytes and EnetEvent.get_datagram() wraps it in a
Datagram for a DatagramIterator.
dg = Datagram()
dg.add_uint8(MSG_MOVE)
dg.add_float32(x)
dg.add_float32(y)
peer.send_datagram(CHANNEL_GAME, dg)
...
dg = event.get_datagram() # keep this reference
it = DatagramIterator(dg)
kind = it.get_uint8()
Keep the Datagram in a variable for as long as the
DatagramIterator reads from it, as with any datagram: an iterator
constructed on a temporary reads freed memory.
A DatagramIterator raises when asked for more than the datagram
holds. A message handler that trusts the wire will therefore raise on the
first truncated or malformed packet; catch around the handler (see
The Service Loop) so one bad packet does not take the loop with it.
Channels¶
Every connection has a number of channels, channel_limit on the host and
channel_count on EnetHost.connect(). Ordering is enforced per
channel: a reliable packet on channel 1 is never delayed behind an unreliable
one on channel 0. A common split is one channel for control messages that
must arrive in order and one for state that is superseded every frame.
Reliability¶
The third argument of send() and
send_datagram() is a set of EnetPeer packet flags:
PF_reliable(the default)Delivered, in order, or the connection times out.
PF_unreliableSent once; may be lost, but arrives in order with respect to other packets on its channel (late packets are dropped).
PF_unsequencedSent once and delivered whenever it arrives, in any order.
PF_unreliable_fragmentAllows a large unreliable packet to be fragmented rather than promoted to reliable.
Packets larger than the path allows are fragmented and reassembled
automatically; reliable packets always, unreliable ones only with the flag.
EnetEvent.packet_flags on a received event carries the flags the
sender used.
Broadcast¶
EnetHost.broadcast() and EnetHost.broadcast_datagram() send one
message to every connected peer of a host, which is how a server distributes
its state. Sending to a subset is a loop over the peers you keep.
Compression and bandwidth¶
EnetHost.compress_with_range_coder() enables ENet’s built-in
compression for a host’s traffic; both ends of every connection must enable
it. The incoming_bandwidth/outgoing_bandwidth arguments of the host
constructors, in bytes per second, let ENet’s throttle know what the link can
take (0 means unlimited).
Statistics¶
A peer reports round_trip_time in milliseconds and
packet_loss as a fraction scaled to
ENET_PEER_PACKET_LOSS_SCALE (65536). A host counts
get_total_sent_data(),
get_total_received_data() and the packet totals since
reset_totals().