mirror of
https://github.com/supabase/supabase.git
synced 2026-07-07 03:34:27 +08:00
192 lines
4.9 KiB
Plaintext
192 lines
4.9 KiB
Plaintext
---
|
|
id: 'protocol'
|
|
title: 'Realtime Protocol'
|
|
description: '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).
|
|
|
|
```ts
|
|
{
|
|
"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
|
|
}
|
|
```
|
|
|
|
<Admonition type="note">
|
|
|
|
The `in` filter has the format `COLUMN_NAME=in.(value1,value2,value3)`. However, other filters use the format `COLUMN_NAME=FILTER_NAME.value`.
|
|
|
|
</Admonition>
|
|
|
|
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.
|
|
|
|
```ts
|
|
{
|
|
"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.
|
|
|
|
```ts
|
|
{
|
|
"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.
|
|
|
|
```ts
|
|
{
|
|
"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.
|
|
|
|
```ts
|
|
{
|
|
"event": "access_token",
|
|
"topic": string,
|
|
"payload":{
|
|
"access_token": string
|
|
},
|
|
"ref": string
|
|
}
|
|
```
|
|
|
|
## Postgres CDC message
|
|
|
|
Realtime sends a message with the following structure
|
|
|
|
```ts
|
|
{
|
|
"event": "postgres_changes",
|
|
"topic": string,
|
|
"payload": {
|
|
"data": {
|
|
"columns": Array<{name: string, type: string}>,
|
|
"commit_timestamp": string,
|
|
"errors": null | string,
|
|
"old_record": {"id": number | string},
|
|
"record": {[key: string]: boolean | number | string | null},
|
|
"type": "*" | "INSERT" | "UPDATE" | "DELETE",
|
|
"schema": string,
|
|
"table": string
|
|
},
|
|
"ids": Array<number>
|
|
},
|
|
"ref": null
|
|
}
|
|
```
|
|
|
|
## Broadcast message
|
|
|
|
Structure of the broadcast event
|
|
|
|
```ts
|
|
{
|
|
"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.
|
|
|
|
```ts
|
|
{
|
|
"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.
|
|
|
|
```ts
|
|
{
|
|
"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
|
|
}
|
|
```
|