Realtime

Realtime Protocol

Understanding 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).

{
   "event": "phx_join",
   "topic": string,
   "payload": {
      "config": {
         "broadcast": {
            "self": boolean
         },
         "presence": {
            "key": string
         },
         "postgres_changes": [
            {
               "event": "*" | "INSERT" | "UPDATE" | "DELETE",
               "schema": string,
               "table": string,
               "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" +  '.' + string
            }
         ]
      }
   },
   "ref": string
}

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.

{
   "event": "phx_reply",
   "topic": string,
   "payload": {
      "response": {
         "postgres_changes": [
            {
               "id": number,
               "event": "*" | "INSERT" | "UPDATE" | "DELETE",
               "schema": string,
               "table": string,
               "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" +  '.' + string
            }
         ]
      },
      "status": "ok" | "error"
   },
   "ref": string
}

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.

{
   "event": "system",
   "topic": string,
   "payload":{
      "channel": string,
      "extension": "postgres_changes",
      "message": "Subscribed to PostgreSQL" | "Subscribing to PostgreSQL failed",
      "status": "ok" | "error"
   },
   "ref": null,
}

Heartbeat

The heartbeat message should be sent every 30 seconds to avoid a connection timeout.

{
   "event": "heartbeat",
   "topic": "phoenix",
   "payload": {},
   "ref": string
}

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.

{
   "event": "access_token",
   "topic": string,
   "payload":{
      "access_token": string
   },
   "ref": string
}

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.

{
   "event": "postgres_changes",
   "topic": string,
   "payload": {
      "data": {
         schema: string,
         table: string,
         commit_timestamp: string,
         eventType: "*" | "INSERT" | "UPDATE" | "DELETE",
         new: {[key: string]: boolean | number | string | null},
         old: {[key: string]: number | string},
         errors: string | null
      },
      "ids": Array<number>
   },
   "ref": null
}

Broadcast message

Structure of the broadcast event

{
   "event": "broadcast",
   "topic": string,
   "payload": {
      "event": string,
      "payload": {[key: string]: boolean | number | string | null | undefined},
      "type": "broadcast"
   },
   "ref": null
}

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.

{
   "event": "presence_state",
   "topic": string,
   "payload": {
      [key: string]: {metas: Array<{phx_ref: string, name: string, t: float}>}
   },
   "ref": null
}

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.

{
   "event": "presence_diff",
   "topic": string,
   "payload": {
      "joins": {metas: Array<{phx_ref: string, name: string, t: float}>},
      "leaves": {metas: Array<{phx_ref: string, name: string, t: float}>}
   },
   "ref": null
}

Resources

Features

Company

Copyright © 2024. All rights reserved.