实时协议

实时协议是一组消息格式,用于在实时客户端和服务器之间通过 WebSocket 连接进行通信。这些消息用于启动连接、更新访问令牌、接收系统状态更新以及从 Postgres 数据库接收实时更新。

连接

在初始消息中,客户端发送一条消息,指定他们想要使用的功能(广播、状态、Postgres 更改)。

1{
2   "event": "phx_join",
3   "topic": string,
4   "payload": {
5      "config": {
6         "broadcast": {
7            "self": boolean
8         },
9         "presence": {
10            "key": string
11         },
12         "postgres_changes": [
13            {
14               "event": "*" | "INSERT" | "UPDATE" | "DELETE",
15               "schema": string,
16               "table": string,
17               "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" +  '.' + string
18            }
19         ]
20      }
21   },
22   "ref": string
23}

note

in 筛选器的格式为 COLUMN_NAME=in.(value1,value2,value3)。但是,其他筛选器使用 COLUMN_NAME=FILTER_NAME.value 格式。

作为响应,服务器发送具有唯一 ID 的 Postgres 配置。使用此 ID,客户端应将传入的更改路由到相应的回调。

1{
2   "event": "phx_reply",
3   "topic": string,
4   "payload": {
5      "response": {
6         "postgres_changes": [
7            {
8               "id": number,
9               "event": "*" | "INSERT" | "UPDATE" | "DELETE",
10               "schema": string,
11               "table": string,
12               "filter": string + '=' + "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" +  '.' + string
13            }
14         ]
15      },
16      "status": "ok" | "error"
17   },
18   "ref": string
19}

系统消息

系统消息用于通知客户端 Postgres 订阅的状态。payload.status指示订阅是否成功。 payload.message 的正文可以是“订阅 PostgreSQL”或“订阅 PostgreSQL 失败”,并带有订阅参数。

1{
2   "event": "system",
3   "topic": string,
4   "payload":{
5      "channel": string,
6      "extension": "postgres_changes",
7      "message": "Subscribed to PostgreSQL" | "Subscribing to PostgreSQL failed",
8      "status": "ok" | "error"
9   },
10   "ref": null,
11}

心跳

检测信号消息应每 30 秒发送一次,以避免连接超时。

1{
2   "event": "heartbeat",
3   "topic": "phoenix",
4   "payload": {},
5   "ref": string
6}

访问令牌

若要更新访问令牌,需要向服务器发送一条消息,在payload.access_token值中指定新令牌。

1{
2   "event": "access_token",
3   "topic": string,
4   "payload":{
5      "access_token": string
6   },
7   "ref": string
8}

Postgres CDC 消息#

Realtime 发送具有以下结构的消息

1{
2   "event": "postgres_changes",
3   "topic": string,
4   "payload": {
5      "data": {
6         "columns": Array<{name: string, type: string}>,
7         "commit_timestamp": string,
8         "errors": null | string,
9         "old_record": {"id": number | string},
10         "record": {[key: string]: boolean | number | string | null},
11         "type": "*" | "INSERT" | "UPDATE" | "DELETE",
12         "schema": string,
13         "table": string
14      },
15      "ids": Array<number>
16   },
17   "ref": null
18}

广播消息

广播事件的结构

1{
2   "event": "broadcast",
3   "topic": string,
4   "payload": {
5      "event": string,
6      "payload": {[key: string]: boolean | number | string | null | undefined},
7      "type": "broadcast"
8   },
9   "ref": null
10}

状态消息

状态事件允许客户端实时监控其他客户端的联机状态。

状态更新

加入后,服务器会向客户端发送一条包含状态信息的presence_state消息。payload 字段包含 UUID 格式的密钥,其中每个密钥表示一个客户端,其值是一个 JSON 对象,其中包含有关该客户端的信息。

1{
2   "event": "presence_state",
3   "topic": string,
4   "payload": {
5      [key: string]: {metas: Array<{phx_ref: string, name: string, t: float}>}
6   },
7   "ref": null
8}

差异更新

更改状态(例如客户端加入或离开)后,服务器会发送一条presence_diff消息以更新客户端的状态视图。payload 字段包含两个键,即 joinleaves,它们分别表示已加入和离开的客户端。与每个键关联的值是客户端的 UUID。

1{
2   "event": "presence_diff",
3   "topic": string,
4   "payload": {
5      "joins": {metas: Array<{phx_ref: string, name: string, t: float}>},
6      "leaves": {metas: Array<{phx_ref: string, name: string, t: float}>}
7   },
8   "ref": null
9}