Supabase实时订阅概述 #

一、实时订阅概述 #

1.1 什么是Realtime #

text
Supabase Realtime
├── 基于WebSocket的实时通信
├── 数据库变更监听
├── 广播消息
├── 在线状态
└── 低延迟实时更新

1.2 订阅模式 #

模式 说明 用途
PostgreSQL Changes 数据库变更监听 数据同步
Broadcast 广播消息 实时通信
Presence 在线状态 协作应用

1.3 架构图 #

text
┌─────────────────────────────────────────────────────────────┐
│                        客户端应用                            │
│         Web / Mobile / Desktop                              │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ WebSocket
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Supabase Realtime                        │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐           │
│  │  Postgres   │ │  Broadcast  │ │  Presence   │           │
│  │  Changes    │ │             │ │             │           │
│  └─────────────┘ └─────────────┘ └─────────────┘           │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    PostgreSQL                               │
│              数据变更 → 实时推送                             │
└─────────────────────────────────────────────────────────────┘

二、启用Realtime #

2.1 Dashboard配置 #

text
Dashboard > Database > Replication

配置步骤
├── 1. 找到要启用实时订阅的表
├── 2. 开启Replication
└── 3. 选择要监听的列

2.2 SQL配置 #

sql
-- 启用表的实时订阅
ALTER PUBLICATION supabase_realtime ADD TABLE messages;

-- 移除表的实时订阅
ALTER PUBLICATION supabase_realtime DROP TABLE messages;

-- 查看已启用的表
SELECT * FROM pg_publication_tables 
WHERE pubname = 'supabase_realtime';

三、基础订阅 #

3.1 创建频道 #

typescript
// 创建频道
const channel = supabase.channel('my-channel')

// 订阅
channel.subscribe((status) => {
  if (status === 'SUBSCRIBED') {
    console.log('Connected!')
  }
})

3.2 监听数据库变更 #

typescript
// 监听所有变更
const channel = supabase
  .channel('schema-db-changes')
  .on(
    'postgres_changes',
    {
      event: '*',
      schema: 'public',
      table: 'messages',
    },
    (payload) => {
      console.log('Change received!', payload)
    }
  )
  .subscribe()

3.3 监听特定事件 #

typescript
// 监听INSERT
const channel = supabase
  .channel('inserts')
  .on(
    'postgres_changes',
    {
      event: 'INSERT',
      schema: 'public',
      table: 'messages',
    },
    (payload) => {
      console.log('New message:', payload.new)
    }
  )
  .subscribe()

// 监听UPDATE
const channel = supabase
  .channel('updates')
  .on(
    'postgres_changes',
    {
      event: 'UPDATE',
      schema: 'public',
      table: 'messages',
    },
    (payload) => {
      console.log('Updated:', payload.old, '→', payload.new)
    }
  )
  .subscribe()

// 监听DELETE
const channel = supabase
  .channel('deletes')
  .on(
    'postgres_changes',
    {
      event: 'DELETE',
      schema: 'public',
      table: 'messages',
    },
    (payload) => {
      console.log('Deleted:', payload.old)
    }
  )
  .subscribe()

四、过滤订阅 #

4.1 按条件过滤 #

typescript
// 只监听特定用户的变更
const channel = supabase
  .channel('user-messages')
  .on(
    'postgres_changes',
    {
      event: '*',
      schema: 'public',
      table: 'messages',
      filter: 'user_id=eq.123',
    },
    (payload) => {
      console.log('User message changed:', payload)
    }
  )
  .subscribe()

4.2 过滤操作符 #

typescript
// 等于
filter: 'column=eq.value'

// 不等于
filter: 'column=neq.value'

// 大于
filter: 'column=gt.value'

// 小于
filter: 'column=lt.value'

// 大于等于
filter: 'column=gte.value'

// 小于等于
filter: 'column=lte.value'

// IN
filter: 'column=in.(value1,value2,value3)'

五、取消订阅 #

5.1 取消单个频道 #

typescript
// 取消订阅
await channel.unsubscribe()

5.2 取消所有订阅 #

typescript
// 取消所有频道
await supabase.removeAllChannels()

六、连接状态 #

6.1 监听连接状态 #

typescript
const channel = supabase
  .channel('status-channel')
  .subscribe((status) => {
    switch (status) {
      case 'SUBSCRIBED':
        console.log('Connected and subscribed')
        break
      case 'TIMED_OUT':
        console.log('Connection timed out')
        break
      case 'CLOSED':
        console.log('Connection closed')
        break
      case 'CHANNEL_ERROR':
        console.log('Channel error')
        break
    }
  })

七、配置选项 #

7.1 客户端配置 #

typescript
const supabase = createClient(url, key, {
  realtime: {
    params: {
      eventsPerSecond: 10,  // 每秒事件数限制
    },
  },
})

八、最佳实践 #

8.1 性能优化 #

text
实时订阅优化建议
├── 只订阅需要的表
├── 使用过滤减少数据量
├── 及时取消不用的订阅
├── 处理断线重连
└── 限制事件频率

8.2 错误处理 #

typescript
const channel = supabase
  .channel('error-handling')
  .on('postgres_changes', { ... }, (payload) => {
    // 处理数据
  })
  .subscribe((status, err) => {
    if (status === 'CHANNEL_ERROR') {
      console.error('Subscription error:', err)
      // 重试或通知用户
    }
  })

九、总结 #

实时订阅要点:

操作 方法
创建频道 channel(name)
监听变更 on(‘postgres_changes’, options, callback)
订阅 subscribe()
取消订阅 unsubscribe()

下一步,让我们学习数据库变更监听!

最后更新:2026-03-28