实时

实时概念

了解 Supabase Realtime 中的频道和其他扩展功能


您可以使用 Supabase Realtime 构建具有协作/多人功能的实时应用程序。它包含三个核心扩展:

频道(Channels)

频道是 Realtime 的基础构建模块。您可以将频道视为聊天室,类似于 Discord 或 Slack 的频道,参与者可以看到谁在线以及收发消息。

当初始化 Supabase Realtime 客户端时,您需要定义一个唯一引用频道的topic。客户端可以通过频道双向收发消息。

1
2
3
4
5
import { createClient } from '@supabase/supabase-js'const supabase = createClient('https://<project>.supabase.co', '<your-anon-key>')const roomOne = supabase.channel('room-one') // 在此设置您的主题(topic)

广播

实时广播遵循发布-订阅模式,客户端基于唯一主题向频道发布消息。例如,用户可以向主题为room-one的频道发送消息。

1
2
3
4
5
6
7
8
9
10
import { createClient } from '@supabase/supabase-js'const supabase = createClient('https://<project>.supabase.co', '<your-anon-key>')const roomOne = supabase.channel('room-one') // 在此设置您的主题// ---cut---roomOne.send({ type: 'broadcast', event: 'test', payload: { message: 'hello, world' },})

其他客户端可以通过订阅主题为room-one的频道实时接收消息。只要这些客户端保持订阅并连接到同一频道主题,就会持续接收消息。

一个典型用例是在线游戏中与其他客户端共享用户的鼠标位置。

在线状态(Presence)

在线状态功能可用于在频道(Channel)内与他人共享个人状态。

1
2
3
4
5
6
7
8
9
import { createClient } from '@supabase/supabase-js'const supabase = createClient('https://<project>.supabase.co', '<your-anon-key>')const roomOne = supabase.channel('room-one') // 在此设置您的主题// ---cut---const presenceTrackStatus = await roomOne.track({ user: 'user-1', online_at: new Date().toISOString(),})

每个客户端维护自己的状态,这些状态会被合并为该频道主题的"共享状态"。它通常用于共享状态(例如"在线"或"不活跃")。在线状态的巧妙之处在于,如果客户端突然断开连接(例如掉线),其状态会自动从共享状态中移除。如果您曾经尝试构建过处理意外断线的"我在线"功能,就会体会到这个功能有多么实用。

当新客户端订阅频道时,它会立即在单条消息中接收频道的最新状态,因为这些状态由Realtime服务器维护。

Postgres 变更监听

Postgres 变更监听扩展能够监听数据库变更并将这些变更发送给客户端。客户端需要使用 JWT 进行订阅,该 JWT 会根据数据库的行级安全策略决定客户端有权接收哪些变更。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { createClient } from '@supabase/supabase-js'const supabase = createClient('your_project_url', 'your_supabase_api_key')// ---cut---const allChanges = supabase .channel('schema-db-changes') .on( 'postgres_changes', { event: '*', schema: 'public', }, (payload) => console.log(payload) ) .subscribe()

任何持有使用项目 JWT 密钥签名的有效 JWT 的用户都能监听数据库变更,除非表启用了行级安全并配置了相应策略。

客户端可以选择接收一个模式中所有变更、模式中某个表的变更或表中某列值的变更,包括INSERTUPDATEDELETE*(全部)操作。客户端应仅监听public模式中的表,且必须首先启用希望客户端监听的表。

广播与在线状态的选择

我们建议默认使用广播(Broadcast),仅在必要时使用在线状态(Presence)。在线状态功能使用内存中的无冲突复制数据类型(CRDT)来以最终一致的方式跟踪和同步共享状态。它会计算现有状态与新状态变更之间的差异,并通过广播发送必要的更新给客户端。这一过程计算密集,因此应谨慎使用。如果使用在线状态功能,最好对变更进行节流,降低更新发送频率。