Notify API
Overview
Custom reliable/unreliable transport layer with fragmentation, acknowledgment tracking and delivery callbacks.
All types live in the SharedMode::Notify namespace.
Header: Notify.h
Connection
Manages two channels (Game and Streaming), 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. |
Public Methods
| Method | Signature | Description |
|---|---|---|
CanQueue |
bool CanQueue(Channel &chan) |
Returns true if the channel can accept more data for queuing. |
Queue |
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 both 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). |
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 _reserved_0;
uint8_t Channel;
uint8_t _reserved_1;
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. |
Channel |
2 | 1 | Channel this fragment belongs to. |
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 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. |
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 SDK provides PhotonNotifyPlatform which bridges the Notify protocol to the Photon transport layer.
Engine integrations do not need to implement this interface directly.
Constants
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