Notify API
Overview
Custom reliable/unreliable transport layer with fragmentation, acknowledgment tracking and delivery callbacks.
All types live in the FusionCore::Notify namespace.
Header: Notify.h
Connection
Manages three channels (Game, Streaming and Unreliable), handles fragmentation, acknowledgments and delivery notifications.
Constructor
C++
explicit Connection(Platform &platform);
Create a connection bound to a platform implementation. Non-copyable.
Public Fields
| Field | Type | Description |
|---|---|---|
Game |
Channel |
Channel 1: unreliable, used for state updates. |
Streaming |
Channel |
Channel 2: reliable, used for RPCs and guaranteed delivery. |
Unreliable |
Channel |
Channel 3: unreliable, used for unreliable RPCs. |
Public Methods
| Method | Signature | Description |
|---|---|---|
CanQueue |
static bool CanQueue(Channel &chan) |
Returns true if the channel can accept more data for queuing. |
Queue |
static bool Queue(Channel &chan, Data data, void *user) |
Queue data for sending on a channel. user is an opaque pointer passed to delivery/loss callbacks. Returns true on success. |
Send |
void Send() |
Flush all queued fragments across all three channels. Calls Platform::Send() for each outgoing packet. |
Update |
void Update() |
Process pending acknowledgments and detect lost packets. Call once per frame. |
Receive |
int Receive(Data data) |
Process an incoming packet. Returns RECV_RESULT_NONE on success or RECV_RESULT_DISCONNECT on fatal error. |
Receive |
int Receive(Channel &chan, FragmentHeader header, Data data) |
Process an incoming fragment for a specific channel. |
Channel
Represents a single communication channel (reliable or unreliable) with send/receive queues.
C++
struct Channel {
uint8_t Id{0};
bool Reliable{false};
size_t MtuData;
LinkList<FragmentGroup> Notify{};
uint32_t SendGroup{0};
LinkList<Fragment> SendQueue{};
LinkList<Fragment> ResendQueue{};
uint32_t RecvGroup{0};
LinkList<Fragment> RecvList{};
};
| Field | Type | Description |
|---|---|---|
Id |
uint8_t |
Channel identifier (1 = Game, 2 = Streaming, 3 = Unreliable). |
Reliable |
bool |
True for reliable delivery with resends. |
MtuData |
size_t |
Maximum payload per fragment (PACKET_MTU_BYTES - sizeof(FragmentHeader)). |
Notify |
LinkList<FragmentGroup> |
Pending delivery notifications. |
SendGroup |
uint32_t |
Next send group counter. |
SendQueue |
LinkList<Fragment> |
Fragments waiting to be sent. |
ResendQueue |
LinkList<Fragment> |
Fragments pending resend (reliable only). |
RecvGroup |
uint32_t |
Next expected receive group. |
RecvList |
LinkList<Fragment> |
Received fragments awaiting reassembly. |
Constructor
C++
Channel(uint8_t id, bool reliable);
Non-copyable.
FragmentHeader
Wire format header prepended to every fragment.
C++
struct FragmentHeader {
uint8_t Flags;
uint8_t Version;
uint8_t Channel;
uint8_t Reserved1;
uint16_t Sequence;
uint16_t AckSequence;
uint64_t AckMask;
uint32_t FragGroup;
uint32_t FragIndex;
};
static_assert(sizeof(FragmentHeader) == 24);
| Field | Offset | Size | Description |
|---|---|---|---|
Flags |
0 | 1 | Bitfield controlling fragment contents. |
Version |
1 | 1 | Notify protocol version (NOTIFY_VERSION). |
Channel |
2 | 1 | Channel this fragment belongs to. |
Reserved1 |
3 | 1 | Reserved padding byte. |
Sequence |
4 | 2 | Monotonically increasing send sequence. |
AckSequence |
6 | 2 | Highest remote sequence acknowledged. |
AckMask |
8 | 8 | Bitmask of the 64 packets preceding AckSequence. |
FragGroup |
16 | 4 | Groups fragments that form a single logical message. |
FragIndex |
20 | 4 | Position of this fragment within the group. |
Fragment
A single fragment in a send or receive queue.
C++
struct Fragment {
Fragment *Prev{nullptr};
Fragment *Next{nullptr};
FragmentGroup *Group{nullptr};
double SendTime{0};
FragmentHeader Header{};
Data Data{};
};
| Field | Type | Description |
|---|---|---|
Prev / Next |
Fragment * |
LinkList pointers. |
Group |
FragmentGroup * |
Parent fragment group. |
SendTime |
double |
Timestamp when the fragment was sent. |
Header |
FragmentHeader |
Wire header for this fragment. |
Data |
Data |
Payload bytes. |
Non-copyable.
FragmentGroup
Groups multiple fragments into a single logical message. Tracks delivery status.
C++
struct FragmentGroup {
FragmentGroup *Prev{nullptr};
FragmentGroup *Next{nullptr};
void *User{nullptr};
Data Data{};
std::optional<bool> WasLost{};
std::optional<bool> WasDelivered{};
uint32_t Group{0};
uint32_t Count{0};
uint8_t *Delivered{nullptr};
uint32_t DeliveredCount{0};
};
| Field | Type | Description |
|---|---|---|
User |
void * |
Opaque pointer passed to delivery/loss callbacks. |
Data |
Data |
Reassembled payload (populated on full delivery). |
WasLost |
optional<bool> |
Set to true if any fragment was lost. |
WasDelivered |
optional<bool> |
Set to true if all fragments were delivered. |
Group |
uint32_t |
Group identifier. |
Count |
uint32_t |
Total fragment count in the group. |
Delivered |
uint8_t * |
Per-fragment delivery bitmap. |
DeliveredCount |
uint32_t |
Number of fragments confirmed delivered. |
Methods
| Method | Signature | Description |
|---|---|---|
IsDone |
bool IsDone() const |
Returns true if the group outcome (lost or delivered) has been determined. |
SetDelivered |
void SetDelivered(Fragment *fragment) |
Mark a fragment as delivered. When all fragments are delivered, sets WasDelivered. |
Non-copyable.
Platform
Abstract interface that the transport implementation must provide.
The Connection calls these methods during its operation.
C++
class Platform {
public:
virtual ~Platform() = default;
virtual double Clock() = 0;
virtual bool Stopped() = 0;
virtual void Send(Connection *connection, Data data) = 0;
virtual void Recv(Connection *connection, Channel &channel, Data data) = 0;
virtual void Lost(Connection *connection, Channel &channel, void *user, Data data) = 0;
virtual void Delivered(Connection *connection, Channel &channel, void *user, Data data) = 0;
};
| Method | Description |
|---|---|
Clock() |
Return the current time in seconds (monotonic). Used for RTT calculation and resend timing. |
Stopped() |
Return true once the transport has shut down. The connection checks this inside its processing loops and aborts delivery when it returns true. |
Send(connection, data) |
Transmit a raw packet over the network. |
Recv(connection, channel, data) |
Called when a complete message is reassembled from fragments. |
Lost(connection, channel, user, data) |
Called when a message is determined to be lost. user is the opaque pointer from Queue(). |
Delivered(connection, channel, user, data) |
Called when a message is confirmed delivered by the remote end. user is the opaque pointer from Queue(). |
The Data passed to Send() may alias a stack buffer inside the connection.
Implementations must consume the bytes synchronously before returning.
Copy the payload if it needs to be deferred or queued.
The SDK provides PhotonNotifyPlatform which bridges the Notify protocol to the Photon transport layer.
Engine integrations do not need to implement this interface directly.
Constants
Protocol
| Constant | Value | Description |
|---|---|---|
NOTIFY_VERSION |
1 | Notify wire protocol version, written into FragmentHeader::Version. |
MTU and Payload
| Constant | Value | Description |
|---|---|---|
DEFAULT_HEADERS |
144 | IP + UDP + Photon overhead (40 + 8 + 96 bytes). |
MAX_MTU_BYTES_TOTAL |
1280 | Maximum packet size (IPv6 minimum MTU). |
MAX_MTU_BYTES_PAYLOAD |
1136 | Usable payload after header subtraction. |
PACKET_MTU_BYTES |
1136 | Payload rounded down to 8-byte alignment. |
Receive Result Codes
| Constant | Value | Description |
|---|---|---|
RECV_RESULT_NONE |
0 | Packet processed successfully. |
RECV_RESULT_DISCONNECT |
2 | Fatal error -- connection should be dropped. |
Fragment Flags
| Constant | Value | Description |
|---|---|---|
FRAG_FLAG_DATA |
1 << 1 |
Fragment carries payload data. |
FRAG_FLAG_ACKS |
1 << 2 |
Fragment carries acknowledgment data. |
FRAG_FLAG_LAST_FRAG |
1 << 7 |
Last fragment in the group. |
Related
- Architecture -- Layered design showing Notify in the stack
- Client API -- Fusion client that sits above Notify