实时概念

您可以使用Supabase Realtime来构建具有协作/多人游戏功能的实时应用程序。它包括 3 个核心功能:

  • Broadcast: 向其他连接的客户端发送快速、短暂的消息。例如,您可以使用它来跟踪鼠标移动。
  • Presence: 在连接的客户端之间发送用户状态。您可以使用它来显示“在线”状态,当用户断开连接时,该状态会消失。
  • Postgres Changes: 实时接收数据库更改。

渠道

通道是实时的基本构建块。您可以将频道视为聊天室,类似于 Discord 或 Slack 频道,参与者可以在其中查看谁在线并发送和接收消息。

初始化 Supabase Realtime 客户端时,您可以定义一个唯一引用通道的主题。客户端可以通过通道双向发送和接收消息。

1import { createClient } from '@supabase/supabase-js'
2
3const client = createClient('https://<project>.supabase.co', '<your-anon-key>')
4
5const roomOne = client.channel('room-one') // set your topic here

广播

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

1roomOne.send({
2  type: 'broadcast',
3  event: 'test',
4  payload: { message: 'hello, world' },
5})

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

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

Presence#

Presence 可用于与频道内的其他人共享个人的状态。

1const presenceTrackStatus = await roomOne.track({
2  user: 'user-1',
3  online_at: new Date().toISOString(),
4})

每个客户端都维护自己的状态,然后将其组合到该 Channel 主题的“共享状态”中。它通常用于共享状态(例如:“在线”或“非活动”)。状态的巧妙之处在于,如果客户端突然断开连接(例如,它们脱机),则其状态会自动从共享状态中删除。如果您曾经尝试过构建一个“我在线”功能来处理意外的断开连接,您会体会到它是多么有用。

当新客户端订阅某个频道时,它将立即在一条消息中收到该频道的最新状态,因为该状态由实时服务器保存。

在广播和存在之间进行选择

我们建议默认使用广播,然后在需要时使用状态。状态利用内存中无冲突复制数据类型 (CRDT) 以最终一致的方式跟踪和同步共享状态。它计算现有状态和新状态更改之间的差异,并通过广播向客户端发送必要的更新。这在计算上很繁重,因此您应该谨慎使用它。如果您使用 Presence,最好限制您的更改,以便减少发送更新的频率。

实时扩展

通道提供通用网络解决方案。Supabase Realtime旨在通过“extensions”来利用这个网络原语。我们目前支持一个扩展:Postgres changes。

Postgres 更改#

Postgres 更改扩展侦听数据库更改并将其发送到客户端。客户端需要订阅 JWT,根据数据库的行级别安全性指示允许他们接收哪些更改。

1const allChanges = client
2  .channel('schema-db-changes')
3  .on(
4    'postgres_changes',
5    {
6      event: '*',
7      schema: 'public',
8    },
9    (payload) => console.log(payload)
10  )
11  .subscribe()

任何有权访问使用项目的 JWT 密钥签名的有效 JWT 的人都可以侦听数据库的更改,除非表启用了行级别安全性并制定了策略。

客户端可以选择接收架构中的所有更改、架构中的表或表中的列值的 INSERT、UPDATE、DELETE 或 *(所有)更改。客户端应仅侦听公共架构中的表,并且必须首先启用希望客户端侦听的表。