Skip to content
Realtime

存在

Share state between users with Realtime Presence.

使用实时在线状态来跟踪多个用户之间的状态。

🌐 Use Realtime Presence to track state between multiple users.

用法 #

🌐 Usage

你可以使用 Supabase 客户端库来跟踪用户之间的在线状态。

🌐 You can use the Supabase client libraries to track Presence state between users.

Presence 是如何运作的 #

🌐 How Presence works

Presence 让每个连接的客户端发布一小部分状态——称为“presence 负载”——到共享通道。Supabase 会将每个客户端的负载存储在一个唯一的 presence 键下,并保持所有连接客户端的合并视图。

🌐 Presence lets each connected client publish a small piece of state—called a “presence payload”—to a shared channel. Supabase stores each client’s payload under a unique presence key and keeps a merged view of all connected clients.

当任何客户端订阅、断开连接或更新他们的状态信息时,Supabase 会触发以下三种事件之一:

🌐 When any client subscribes, disconnects, or updates their presence payload, Supabase triggers one of three events:

  • sync — 完整状态已更新
  • join — 一个新客户开始跟踪出勤了
  • leave — 客户端已停止追踪在线状态

presenceState() 返回的完整在线状态看起来是这样的:

🌐 The complete presence state returned by presenceState() looks like this:

1
{
2
"client_key_1": [{ "userId": 1, "typing": false }],
3
"client_key_2": [{ "userId": 2, "typing": true }]
4
}

初始化客户端 #

🌐 Initialize the client

项目的 Connect 对话框 获取项目的 URL 和密钥。

🌐 Get the Project URL and key from the project's Connect dialog.

1
import { createClient } from '@supabase/supabase-js'
2
3
const SUPABASE_URL = 'https://<project>.supabase.co'
4
const SUPABASE_KEY = '<sb_publishable_... key>'
5
6
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)

同步并跟踪状态 #

🌐 Sync and track state

监听 syncjoinleave 事件,这些事件会在任何客户端加入或离开通道,或更改其状态片段时触发:

🌐 Listen to the sync, join, and leave events triggered whenever any client joins or leaves the channel or changes their slice of state:

1
import { createClient } from '@supabase/supabase-js'
2
3
const supabase = createClient('your_project_url', 'your_supabase_api_key')
4
5
// ---cut---
6
const roomOne = supabase.channel('room_01')
7
8
roomOne
9
.on('presence', { event: 'sync' }, () => {
10
const newState = roomOne.presenceState()
11
console.log('sync', newState)
12
})
13
.on('presence', { event: 'join' }, ({ key, newPresences }) => {
14
console.log('join', key, newPresences)
15
})
16
.on('presence', { event: 'leave' }, ({ key, leftPresences }) => {
17
console.log('leave', key, leftPresences)
18
})
19
.subscribe()

发送状态 #

🌐 Sending state

你可以使用 track() 向所有订阅者发送状态:

🌐 You can send state to all subscribers using track():

1
import { createClient } from '@supabase/supabase-js'
2
const supabase = createClient('your_project_url', 'your_supabase_api_key')
3
4
// ---cut---
5
const roomOne = supabase.channel('room_01')
6
7
const userStatus = {
8
user: 'user-1',
9
online_at: new Date().toISOString(),
10
}
11
12
roomOne.subscribe(async (status) => {
13
if (status !== 'SUBSCRIBED') { return }
14
15
const presenceTrackStatus = await roomOne.track(userStatus)
16
console.log(presenceTrackStatus)
17
})

一个客户端会接收任何订阅了相同主题(在这个例子中是 room_01)的其他客户端的状态。它也会自动触发自身的 syncjoin 事件处理器。

🌐 A client will receive state from any other client that is subscribed to the same topic (in this case room_01). It will also automatically trigger its own sync and join event handlers.

停止追踪 #

🌐 Stop tracking

你可以使用 untrack() 方法停止追踪出席情况。这将触发 syncleave 事件处理程序。

🌐 You can stop tracking presence using the untrack() method. This will trigger the sync and leave event handlers.

1
import { createClient } from '@supabase/supabase-js'
2
3
const supabase = createClient('your_project_url', 'your_supabase_api_key')
4
const roomOne = supabase.channel('room_01')
5
6
// ---cut---
7
const untrackPresence = async () => {
8
const presenceUntrackStatus = await roomOne.untrack()
9
console.log(presenceUntrackStatus)
10
}
11
12
untrackPresence()

显示选项 #

🌐 Presence options

你可以在初始化 Supabase 客户端时传入配置选项。

🌐 You can pass configuration options while initializing the Supabase Client.

存在键 #

🌐 Presence key

默认情况下,Presence 会在服务器上生成一个唯一的 UUIDv1 密钥来跟踪客户端通道的状态。如果你愿意,可以在创建通道时提供自定义密钥。这个密钥在客户端之间应该是唯一的。

🌐 By default, Presence will generate a unique UUIDv1 key on the server to track a client channel's state. If you prefer, you can provide a custom key when creating the channel. This key should be unique among clients.

1
import { createClient } from '@supabase/supabase-js'
2
3
const supabase = createClient('SUPABASE_URL', 'SUPABASE_PUBLISHABLE_KEY')
4
5
const channelC = supabase.channel('test', {
6
config: {
7
presence: {
8
key: 'userId-123',
9
},
10
},
11
})