2.6 KiB
2.6 KiB
实时功能
监听数据变化
启用表的实时功能
重要:需要监听数据实时变化的数据表必须先通过以下指令启动 RealTime 功能
ALTER PUBLICATION supabase_realtime ADD TABLE public.messages;
监听变化
import { supabase } from 'src/supabase/client.ts';
const currentUserId = getCurrentUserId(); // 获取当前用户ID
const channel = supabase
.channel('messages')
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages' },
(payload) => {
const newMessage = payload.new;
// 只处理其他用户发送的消息,避免重复显示自己的消息
if (newMessage.user_id !== currentUserId) {
setMessages(prev => [...prev, newMessage]);
}
}
)
.subscribe();
// 发送消息的正确做法
const sendMessage = async (content) => {
// 1. 立即添加到本地状态(避免延迟)
const tempMessage = { id: `temp-${Date.now()}`, content, user_id: currentUserId };
setMessages(prev => [...prev, tempMessage]);
// 2. 发送到数据库
const { data, error } = await supabase.from('messages').insert({ content, user_id: currentUserId });
if (error) {
// 发送失败时移除本地消息
setMessages(prev => prev.filter(msg => msg.id !== tempMessage.id));
}
};
// ✅ 清理以防止内存泄漏
return () => { channel.unsubscribe(); };
注意事项
- 记得为实时表设置适当的 RLS 策略
- 发送消息成功后,立即手动将新消息对象添加到本地 messages 数组,不要依赖 Realtime 订阅来显示自己发送的消息(避免延迟)
- Realtime 订阅仅用于接收其他用户发送的消息
用户在线状态
Supabase 提供实时功能来跟踪用户在线状态并在用户间共享状态。
const roomOne = supabase.channel('room_01');
// 同步和跟踪状态
roomOne
.on('presence', { event: 'sync' }, () => {
const newState = roomOne.presenceState();
console.log('sync', newState);
})
.on('presence', { event: 'join' }, ({ key, newPresences }) => {
console.log('join', key, newPresences);
})
.on('presence', { event: 'leave' }, ({ key, leftPresences }) => {
console.log('leave', key, leftPresences);
})
.subscribe();
// 发送状态
const userStatus = {
user: 'user-1',
online_at: new Date().toISOString(),
};
roomOne.subscribe(async (status) => {
if (status !== 'SUBSCRIBED') return;
const presenceTrackStatus = await roomOne.track(userStatus);
console.log(presenceTrackStatus);
});
// ✅ 清理以防止内存泄漏
return () => { roomOne.unsubscribe(); };