Realtime
StorageDB Realtime - PostgreSQL o'zgarishlarini, mijozlar orasidagi xabar almashishni va foydalanuvchi holatini real vaqtda kuzatish.
Kirish
Realtime funksiyasi PostgreSQL ma'lumotlar bazasidagi o'zgarishlarni, broadcast xabarlarini va foydalanuvchilar holati (presence) haqida ma'lumotni real vaqtda olish imkoniyatini beradi.
Uchtа asosiy turdagi voqealar mavjud: (1) Postgres Changes — jadvallar o'zgarishi uchun, RLS hurmat qilinadi; (2) Broadcast — mijozlar orasidagi bevosita xabar almashishi; (3) Presence — qaysi foydalanuvchilar faol ekanligini kuzatish.
WebSocket Ulanish
Realtime xizmatiga WebSocket orqali ulanish kerak. URLda project reference (<REF>) va API key (<ANON_KEY> yoki <SERVICE_KEY>) o'tkaziladi.
Ulanishdan so'ng server ready xabari yuboradi, shunda siz subscribe, join, va boshqa komandalarni yuborshingiz mumkin.
wss://storage.identify.uz/v1/<REF>/realtime/v1/websocket?apikey=<ANON_KEY>
import StorageDB from '@storagedb/client';
const db = new StorageDB({
url: 'https://storage.identify.uz',
apiKey: '<ANON_KEY>',
ref: '<REF>',
});
const channel = db.channel('my-channel');
channel.subscribe();Postgres Changes
Jadvaldagi INSERT, UPDATE, yoki DELETE operatsiyalarini kuzatish uchun avval SQL'da realtime.enable('jadvalnomi') chaqiring, keyin WebSocket'da o'sha jadvalgа subscribe qiling.
RLS (Row Level Security) siyosatlari hurmat qilinadi — har foydalanuvchi faqat o'ziga ko'rinishi mumkin bo'lgan qatorlarni oladi. Service role esa barcha qatorlarni oladi.
UPDATE va DELETE voqealarida old_record (eski qiymatlar) keladi, lekin RLS ostidagi foydalanuvchilar uchun faqat primary key ustunlari jo'natiladi (ma'lumot sirraligi uchun).
-- Service role sifatida bajariladi
SELECT realtime.enable('todos');wscat -c 'wss://storage.identify.uz/v1/<REF>/realtime/v1/websocket?apikey=<ANON_KEY>'
# Ulanishdan so'ng, quyidagini yuboring:
{"type": "subscribe", "table": "todos"}
# Javob:
{"type": "subscribed", "table": "todos"}
# INSERT voqeasini olish:
{"type": "change", "event": "INSERT", "table": "todos", "record": {"id": 1, "title": "Task 1"}}const channel = db.channel('todos')
.on('INSERT', (payload) => {
console.log('Yangi qator qo\'shildi:', payload.record);
})
.on('UPDATE', (payload) => {
console.log('Qator yangilandi:', payload.record);
console.log('Eski qiymatlar:', payload.old_record);
})
.on('DELETE', (payload) => {
console.log('Qator o\'chirildi (PK):', payload.old_record);
})
.on('*', (payload) => {
// Barcha o'zgarishlar
console.log('O\'zgarish:', payload.event);
})
.subscribe();Broadcast — Mijozlar Orasidagi Xabarlar
Broadcast xizmatida ma'lumotlar bazasi bilan bog'lanmagan holda, foydalanuvchilar bir-biriga xabar yuborishlari mumkin (masalan, o'yinchililar o'rtasida, real vaqtda kursorlari ko'rsatish uchun).
Topic'ga join qiling, keyin broadcast buyrug'i bilan xabar yuboring. Bir xil topic'dagi boshqa foydalanuvchilar bu xabarni oladi.
Broadcast serverda saqlanmaydi — faqat faol ulanishlargа jo'natiladi.
# Ulanish va topic'ga qo'shilish
wscat -c 'wss://storage.identify.uz/v1/<REF>/realtime/v1/websocket?apikey=<ANON_KEY>'
{"type": "join", "topic": "gaming-room"}
# Javob:
{"type": "joined", "topic": "gaming-room"}
# Xabar yuborish
{"type": "broadcast", "topic": "gaming-room", "event": "cursor_move", "payload": {"x": 100, "y": 200}}
# Boshqa mijozlar quyidagini oladi:
{"type": "broadcast", "topic": "gaming-room", "event": "cursor_move", "payload": {"x": 100, "y": 200}}const channel = db.channel('gaming-room')
.onBroadcast('cursor_move', (message) => {
console.log('Boshqa foydalanuvchi kursori:', message.payload);
})
.subscribe();
// Xabar yuborish
channel.send('cursor_move', { x: 100, y: 200 });
channel.send('player_action', { action: 'jump' });Presence — Kim Onlayn
Presence orqali foydalanuvchilar o'zlarining holatini (status, ma'lumot) tarqata oladi va boshqalarning holatlarini kuzata oladi.
track(state) bilan o'z holatni belgilang, presenceState() orqali boshqalarning holatlarini oling. Bir key uchun bir nechta state bo'lishi mumkin (masalan, bir foydalanuvchi bir nechta tabdan ulanishi).
Foydalanuvchi jo'nalganda avtomatik ravishda presence_leave xabari jo'natiladi.
# Ulanish
wscat -c 'wss://storage.identify.uz/v1/<REF>/realtime/v1/websocket?apikey=<ANON_KEY>'
# Topic'ga qo'shilish
{"type": "join", "topic": "chatroom"}
# O'z holatni belgilash
{"type": "presence_track", "topic": "chatroom", "key": "user-123", "state": {"username": "Ali", "status": "online"}}
# Javob (barcha foydalanuvchilar):
{"type": "presence_sync", "topic": "chatroom", "state": {"user-123": [{"username": "Ali", "status": "online"}]}}
# Boshqa foydalanuvchi kelmasa:
{"type": "presence_join", "topic": "chatroom", "key": "user-456", "state": {"username": "Bob"}}const channel = db.channel('chatroom')
.onPresenceSync(() => {
const state = channel.presenceState();
console.log('Onlayn foydalanuvchilar:', state);
// state: { 'user-123': [{username: 'Ali', status: 'online'}] }
})
.onPresenceJoin((event) => {
console.log('Yangi foydalanuvchi:', event.key, event.state);
})
.onPresenceLeave((event) => {
console.log('Foydalanuvchi ketdi:', event.key);
})
.subscribe();
// O'z holatni belgilash
channel.track({ username: 'Ali', status: 'online' });
// Holatni yangilash (track qayta chaqirish)
setTimeout(() => {
channel.track({ username: 'Ali', status: 'idle' });
}, 5000);
// Holatni olib tashlash
channel.untrack();RLS va Xavfsizlik
Postgres Changes avtomatik ravishda RLS siyosatlarini hurmat qiladi. Anon key (ochiq) ishlatuvchi faqat o'ziga ko'rinishi mumkin bo'lgan qatorlarni oladi.
Service key (maxfiy) rola BYPASSRLS ni qo'lladi, shuning uchun barcha qatorlarni oladi.
Har voqea har obunachi uchun alohida tekshiriladi. DELETE voqeasida qator yo'qolgan bo'lgani sababli faqat primary key ustunlari jo'natiladi.