Skip to content
Realtime

订阅数据库变化

Listen to database changes in real-time from your website or application.

你可以使用 Supabase 订阅实时数据库的变化。有两种可用的选项:

🌐 You can use Supabase to subscribe to real-time database changes. There are two options available:

  1. 广播。这是推荐的可扩展性和安全性的方法。
  2. Postgres 变更。这是一个更简单的方法。设置要求较少,但扩展性不如 Broadcast。

使用广播 #

🌐 Using Broadcast

要在记录被创建、更新或删除时自动发送消息,我们可以把一个 Postgres 触发器 附加到任意表。Supabase Realtime 提供了一个 realtime.broadcast_changes() 函数,我们可以结合触发器来使用。这个函数会使用一个私有通道,并且需要满足广播授权的 RLS 策略。

🌐 To automatically send messages when a record is created, updated, or deleted, we can attach a Postgres trigger to any table. Supabase Realtime provides a realtime.broadcast_changes() function which we can use in conjunction with a trigger. This function will use a private channel and needs broadcast authorization RLS policies to be met.

播放授权 #

🌐 Broadcast authorization

实时授权 是接收广播消息所必需的。这是一个允许经过身份验证的用户收听主题消息的策略示例:

1
create policy "Authenticated users can receive broadcasts"
2
on "realtime"."messages"
3
for select
4
to authenticated
5
using ( true );

创建触发器函数 #

🌐 Create a trigger function

创建一个函数,每当记录被创建、更新或删除时调用。这个函数将使用 Postgres 的一些原生 触发器变量。在这个例子中,我们希望有一个名为 topic:<record id> 的主题,我们将向其广播事件。

🌐 Create a function to call whenever a record is created, updated, or deleted. This function will make use of some of Postgres's native trigger variables. For this example, we want to have a topic with the name topic:<record id> to which we're going to broadcast events.

1
create or replace function public.your_table_changes()
2
returns trigger
3
security definer
4
language plpgsql
5
as $$
6
begin
7
perform realtime.broadcast_changes(
8
'topic:' || coalesce(NEW.id, OLD.id) ::text, -- topic - the topic to which you're broadcasting where you can use the topic id to build the topic name
9
TG_OP, -- event - the event that triggered the function
10
TG_OP, -- operation - the operation that triggered the function
11
TG_TABLE_NAME, -- table - the table that caused the trigger
12
TG_TABLE_SCHEMA, -- schema - the schema of the table that caused the trigger
13
NEW, -- new record - the record after the change
14
OLD -- old record - the record before the change
15
);
16
return null;
17
end;
18
$$;

创建一个触发器 #

🌐 Create a trigger

设置一个触发器,让函数在表格有任何更改后运行。

🌐 Set up a trigger so the function runs after any changes to the table.

1
create trigger handle_your_table_changes
2
after insert or update or delete
3
on public.your_table
4
for each row
5
execute function your_table_changes ();

在客户端监听 #

🌐 Listening on client side

最后,在客户端,监听主题 topic:<record_id> 来接收事件。记得将通道设置为私有通道,因为 realtime.broadcast_changes 使用实时授权。

🌐 Finally, on the client side, listen to the topic topic:<record_id> to receive the events. Remember to set the channel as a private channel, since realtime.broadcast_changes uses Realtime Authorization.

1
import { createClient } from '@supabase/supabase-js'
2
3
const supabase = createClient('your_project_url', 'your_supabase_api_key')
4
5
// ---cut---
6
const gameId = 'id'
7
await supabase.realtime.setAuth() // Needed for Realtime Authorization
8
const changes = supabase
9
.channel(`topic:${gameId}`, {
10
config: { private: true },
11
})
12
.on('broadcast', { event: 'INSERT' }, (payload) => console.log(payload))
13
.on('broadcast', { event: 'UPDATE' }, (payload) => console.log(payload))
14
.on('broadcast', { event: 'DELETE' }, (payload) => console.log(payload))
15
.subscribe()

使用 Postgres 的更改 #

🌐 Using Postgres Changes

Postgres 变更只需要最少的设置,但随着你的应用扩展,会有一些限制。我们建议在大多数情况下使用 Broadcast。

🌐 Postgres Changes require minimal setup, but have some limitations as your application scales. We recommend using Broadcast for most use cases.

启用 Postgres 更改 #

🌐 Enable Postgres Changes

你首先需要创建一个 supabase_realtime 发布,并将你想订阅的表添加到该发布中:

🌐 You'll first need to create a supabase_realtime publication and add your tables (that you want to subscribe to) to the publication:

1
begin;
2
3
-- remove the supabase_realtime publication
4
drop
5
publication if exists supabase_realtime;
6
7
-- re-create the supabase_realtime publication with no tables
8
create publication supabase_realtime;
9
10
commit;
11
12
-- add a table called 'messages' to the publication
13
-- (update this to match your tables)
14
alter
15
publication supabase_realtime add table messages;

流式插入 #

🌐 Streaming inserts

你可以使用 INSERT 事件来实时传输所有新行。

🌐 You can use the INSERT event to stream all new rows.

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

流媒体更新 #

🌐 Streaming updates

你可以使用 UPDATE 事件来流式传输所有更新的行。

🌐 You can use the UPDATE event to stream all updated rows.

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