身為前端開發者,打造一個即時聊天室、一個能即時更新數據的儀表板,這些「即時互動」的應用,往往能大幅提升使用者體驗,要實現這些功能,傳統上需要處理複雜的後端設定、WebSocket 連線管理、資料同步等繁瑣細節,今天介紹的 Supabase Realtime,就是為了解決這些痛點而生。
Supabase Realtime 是一個基於 PostgreSQL 的即時訂閱服務,透過 WebSocket 實現資料庫變更、廣播訊息和用戶狀態同步。它提供了三個核心功能:監聽資料庫變更(Postgres Changes)、即時廣播訊息(Broadcast)、以及用戶在線狀態同步(Presence)。
資料庫變更通知:就像訂閱了一份報紙,只要資料庫裡有任何新的文章、修改或刪除,它都會立刻送到你手上,讓你隨時掌握最新動態。
即時廣播:就像一個廣播電台,可以對著麥克風說話,所有收聽同一個頻道的人都能立刻聽到你的聲音。
在線狀態追蹤:就像進入一個會議室,可以知道誰在裡面、誰離開了,甚至他們現在在做什麼(例如「正在打字」)。
心靈感應與雙向感知:在腦中直接對任何一位、一部分或全體暗影士兵下達命令。這種溝通是即時的,不受距離限制。不僅能下令,還能感知到士兵們的位置、狀態,甚至可以「共享」他們的視野,看到他們所見的景象。
要充分運用 Supabase Realtime,需要理解四個核心概念:
Realtime 的基本單位,用於組織和隔離不同的即時通訊流。每個頻道都有一個獨特的名稱,客戶端可以訂閱一個或多個頻道來接收相關訊息。
想像成不同的「聊天室」或「主題房間」,只有加入特定房間的人才能收到裡面的訊息。例如,你可以建立一個「產品討論」頻道讓產品團隊溝通,或是建立一個「遊戲大廳」頻道讓玩家互動。每個頻道都是獨立的,不會互相干擾。
允許在頻道內向所有訂閱者發送非持久性、低延遲的訊息。這些訊息不會被儲存到資料庫中,純粹用於即時傳遞短暫的狀態資訊。
就像對著麥克風喊話,所有在同一個房間裡的人都能立刻聽到,但訊息不會被記錄下來。適合傳遞「一閃而過」的即時資訊,例如:
用於追蹤和同步頻道內用戶的在線狀態及自定義狀態資訊。當用戶加入或離開頻道時,其他訂閱者會收到通知,並且可以獲取當前所有在線用戶的完整狀態列表。
就像進入一個會議室,可以知道誰在裡面、誰離開了,甚至現在在做什麼。例如,在一個線上協作工具中,可以看到哪些同事在線上,是否正在忙碌,或者正在編輯哪個部分。當有人加入或離開時,也會立刻收到通知。
允許客戶端訂閱 PostgreSQL 資料庫中特定表格的 INSERT, UPDATE, DELETE 事件,並即時接收這些變更。這是基於 PostgreSQL 的邏輯複製功能實現的。
就像訂閱了一份報紙,只要資料庫裡有任何新的文章、修改或刪除,都會立刻收到通知。這對於需要即時更新數據的應用非常有用,例如:
在使用 Supabase Realtime 之前,你需要先初始化 Supabase 客戶端。
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'YOUR_SUPABASE_URL'
const supabaseAnonKey = 'YOUR_SUPABASE_ANON_KEY'
const supabase = createClient(supabaseUrl, supabaseAnonKey)
如何在一個頻道中發送和接收廣播訊息。
// 1. 訂閱一個頻道
const myChannel = supabase.channel('my-broadcast-channel')
// 2. 監聽廣播訊息
myChannel.on('broadcast', { event: 'chat-message' }, (payload) => {
console.log('收到廣播訊息:', payload.payload.message)
}).subscribe()
// 3. 發送廣播訊息 (例如,點擊按鈕時發送)
async function sendMessage() {
const { error } = await myChannel.send({
type: 'broadcast',
event: 'chat-message',
payload: { message: 'Hello, everyone!' },
})
if (error) console.error('發送廣播失敗:', error)
}
// 呼叫 sendMessage() 來發送訊息
// sendMessage()
如何追蹤和顯示在線用戶的狀態。
// 1. 訂閱一個頻道並啟用 Presence
const presenceChannel = supabase.channel('online-users', {
config: { presence: { key: 'user_id_123' } } // 為當前用戶設定一個唯一的 key
})
// 2. 監聽 Presence 事件
presenceChannel.on('presence', { event: 'sync' }, () => {
const presenceState = presenceChannel.presenceState()
console.log('當前在線用戶狀態:', presenceState)
}).on('presence', { event: 'join' }, ({ newPresences }) => {
console.log('新用戶加入:', newPresences)
}).on('presence', { event: 'leave' }, ({ leftPresences }) => {
console.log('用戶離開:', leftPresences)
}).subscribe(async (status) => {
if (status === 'SUBSCRIBED') {
// 3. 追蹤當前用戶的狀態
const { error } = await presenceChannel.track({
user_name: 'William',
online_at: new Date().toISOString(),
status: 'online'
})
if (error) console.error('追蹤狀態失敗:', error)
}
})
// 當用戶離開頁面時,自動移除其狀態
window.addEventListener('beforeunload', () => {
presenceChannel.untrack()
})
要使用 Postgres Changes,需要在 Supabase 後台為你想要監聽的表格啟用 Realtime。
在 Supabase 後台啟用 Realtime for Tables:
訂閱資料庫變更:
// 1. 訂閱 'public' schema 下 'your_table_name' 表格的所有變更
const tableChannel = supabase.channel('any_table_channel_name')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'your_table_name' },
(payload) => {
console.log('資料庫變更:', payload)
// payload.eventType: 'INSERT', 'UPDATE', 'DELETE'
// payload.new: 新增或更新後的數據
// payload.old: 刪除或更新前的數據 (僅在 UPDATE/DELETE 時有)
}
)
.subscribe()
// 只監聽特定事件,例如只監聽新增 (INSERT)
supabase.channel('new-rows')
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'your_table_name' },
(payload) => {
console.log('新增了一行數據:', payload.new)
}
)
.subscribe()
// 或者監聽特定條件的更新
supabase.channel('specific-update')
.on(
'postgres_changes',
{ event: 'UPDATE', schema: 'public', table: 'your_table_name', filter: 'id=eq.123' },
(payload) => {
console.log('ID 為 123 的數據被更新了:', payload.new)
}
)
.subscribe()
除了在程式碼中處理監聽結果外,也可以直接在 Supabase Dashboard 的 Realtime Inspector 中即時查看和測試頻道訊息:
步驟 1:進入 Realtime Inspector
步驟 2:加入頻道並開始監聽
my-broadcast-channel
步驟 3:查看即時訊息
步驟 4:使用篩選功能
實用技巧:
無論想打造即時聊天應用、協同編輯工具、多人遊戲,還是動態儀表板,Supabase Realtime 都能提供扎實的基礎。
有任何想討論歡迎留言,或需要指正的地方請鞭大力一點,歡迎訂閱、按讚加分享,分享給想要提升開發效率的朋友