Realtime Protocol
The Realtime Protocol is a set of message formats used for communication over a WebSocket connection between a Realtime client and server. These messages are used to initiate a connection, update access tokens, receive system status updates, and receive real-time updates from the Postgres database.
Connection
In the initial message, the client sends a message specifying the features they want to use (Broadcast, Presence, Postgres Changes).
_23{_23 "event": "phx_join",_23 "topic": string,_23 "payload": {_23 "config": {_23 "broadcast": {_23 "self": boolean_23 },_23 "presence": {_23 "key": string_23 },_23 "postgres_changes": [_23 {_23 "event": "*" | "INSERT" | "UPDATE" | "DELETE",_23 "schema": string,_23 "table": string,_23 "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" + '.' + string_23 }_23 ]_23 }_23 },_23 "ref": string_23}
The in
filter has the format COLUMN_NAME=in.(value1,value2,value3)
. However, other filters use the format COLUMN_NAME=FILTER_NAME.value
.
In response, the server sends the Postgres configuration with a unique ID. With this ID, the client should route incoming changes to the appropriate callback.
_19{_19 "event": "phx_reply",_19 "topic": string,_19 "payload": {_19 "response": {_19 "postgres_changes": [_19 {_19 "id": number,_19 "event": "*" | "INSERT" | "UPDATE" | "DELETE",_19 "schema": string,_19 "table": string,_19 "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" + '.' + string_19 }_19 ]_19 },_19 "status": "ok" | "error"_19 },_19 "ref": string_19}
System messages
System message are used to inform a client about the status of the Postgres subscription. The payload.status
indicates if the subscription successful or not.
The body of the payload.message
can be "Subscribed to PostgreSQL" or "Subscribing to PostgreSQL failed" with subscription params.
_11{_11 "event": "system",_11 "topic": string,_11 "payload":{_11 "channel": string,_11 "extension": "postgres_changes",_11 "message": "Subscribed to PostgreSQL" | "Subscribing to PostgreSQL failed",_11 "status": "ok" | "error"_11 },_11 "ref": null,_11}
Heartbeat
The heartbeat message should be sent every 30 seconds to avoid a connection timeout.
_10{_10 "event": "heartbeat",_10 "topic": "phoenix",_10 "payload": {},_10 "ref": string_10}
Access token
To update the access token, you need to send to the server a message specifying a new token in the payload.access_token
value.
_10{_10 "event": "access_token",_10 "topic": string,_10 "payload":{_10 "access_token": string_10 },_10 "ref": string_10}
Postgres CDC message
Realtime sends a message with the following structure. By default, the payload only includes new record changes, and the old
entry includes the changed row's primary id. If you want to receive old records, you can set the replicate identity of your table to full. Check out this section of the guide.
_17{_17 "event": "postgres_changes",_17 "topic": string,_17 "payload": {_17 "data": {_17 schema: string,_17 table: string,_17 commit_timestamp: string,_17 eventType: "*" | "INSERT" | "UPDATE" | "DELETE",_17 new: {[key: string]: boolean | number | string | null},_17 old: {[key: string]: number | string},_17 errors: string | null_17 },_17 "ids": Array<number>_17 },_17 "ref": null_17}
Broadcast message
Structure of the broadcast event
_10{_10 "event": "broadcast",_10 "topic": string,_10 "payload": {_10 "event": string,_10 "payload": {[key: string]: boolean | number | string | null | undefined},_10 "type": "broadcast"_10 },_10 "ref": null_10}
Presence message
The Presence events allow clients to monitor the online status of other clients in real-time.
State update
After joining, the server sends a presence_state
message to a client with presence information. The payload field contains keys in UUID format, where each key represents a client and its value is a JSON object containing information about that client.
_10{_10 "event": "presence_state",_10 "topic": string,_10 "payload": {_10 [key: string]: {metas: Array<{phx_ref: string, name: string, t: float}>}_10 },_10 "ref": null_10}
Diff update
After a change to the presence state, such as a client joining or leaving, the server sends a presence_diff message to update the client's view of the presence state. The payload field contains two keys, joins
and leaves
, which represent clients that have joined and left, respectively. The values associated with each key are UUIDs of the clients.
_10{_10 "event": "presence_diff",_10 "topic": string,_10 "payload": {_10 "joins": {metas: Array<{phx_ref: string, name: string, t: float}>},_10 "leaves": {metas: Array<{phx_ref: string, name: string, t: float}>}_10 },_10 "ref": null_10}