การแจ้งเตือนในแอปแบบเรียลไทม์
แสดงการตอบกลับ การกล่าวถึง และการอนุมัติทันทีที่เกิดขึ้นในทุกแท็บที่เปิดอยู่ และส่งการแจ้งเตือนแบบพุชแทนเมื่อผู้ใช้ออฟไลน์
ผู้ใช้สังเกตได้เมื่อผลิตภัณฑ์ตอบสนองทันทีที่มีบางอย่างเกิดขึ้น เช่น มีคนแสดงความคิดเห็นในโพสต์ คำขอได้รับอนุมัติ หรือเพื่อนร่วมทีมกล่าวถึง การโพลล์ทุก 30 วินาทีเพื่อเช็กเรื่องเหล่านี้ทั้งช้าและเปลืองคำขอ เมื่อใช้ Hibira เซิร์ฟเวอร์ของคุณส่งการแจ้งเตือนเพียงครั้งเดียว แล้วทุกแท็บและทุกอุปกรณ์ที่ผู้ใช้เปิดอยู่จะแสดงผลภายในไม่กี่มิลลิวินาที เมื่อผู้ใช้ออฟไลน์ การแจ้งเตือนแบบพุชจะรับหน้าที่ต่อ
สิ่งที่ผู้ใช้ได้รับ
- ป้ายตัวเลขบนกระดิ่งและข้อความแจ้งเตือนที่อัปเดตทันทีในทุกแท็บที่เปิดอยู่
- การแจ้งเตือนเดียวกันบนโทรศัพท์เมื่อปิดแอปอยู่
- เห็นความเคลื่อนไหวใหม่โดยไม่ต้องรีโหลด และตัวนับไม่ค้างเป็นค่าเก่า
ฟีเจอร์ที่ใช้
- การยืนยันตัวตนผู้ใช้ (
pusher.signin()) ผู้ใช้แต่ละคนจึงมีช่องของตัวเองที่มีแต่เขาอ่านได้ sendToUserใน SDK เซิร์ฟเวอร์ทางการ ส่งถึงทุกซ็อกเก็ตของผู้ใช้คนนั้นบนทุกโหนด- การแจ้งเตือนแบบพุช ผ่าน API ที่เข้ากันได้กับ Beams สำหรับผู้ใช้ที่ไม่ได้เชื่อมต่ออยู่
- ช่องส่วนตัวแบบเข้ารหัส (
private-encrypted-) เมื่อการแจ้งเตือนมีข้อมูลที่ควรเข้ารหัสแบบต้นทางถึงปลายทาง
ขั้นที่ 1: ให้ผู้ใช้ลงชื่อเข้าใช้บนซ็อกเก็ต
เพิ่มเส้นทางยืนยันตัวตนผู้ใช้ไว้ข้างเส้นทางยืนยันสิทธิ์ช่อง เส้นทางนี้ทำงานบนเซิร์ฟเวอร์ของคุณและใช้ secret ของแอป
// Express
app.post('/pusher/user-auth', requireLogin, express.urlencoded({ extended: false }), (req, res) => {
const auth = pusher.authenticateUser(req.body.socket_id, {
id: String(req.user.id),
user_info: { name: req.user.name },
});
res.json(auth);
});ในเบราว์เซอร์ ให้เชื่อมต่อตามคู่มือ JavaScript แล้วลงชื่อเข้าใช้:
const pusher = new Pusher(import.meta.env.VITE_PUSHER_APP_KEY, {
cluster: 'ap',
wsHost: 'ws.hibira.io',
wsPort: 443,
wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
userAuthentication: { endpoint: '/pusher/user-auth', transport: 'ajax' },
});
pusher.signin();
pusher.user.bind('notification', (n) => {
bell.increment();
toast.show(n.title, { href: n.url });
});ขั้นที่ 2: ส่งจากเซิร์ฟเวอร์
บันทึกการแจ้งเตือนลงฐานข้อมูลก่อน เพื่อให้รายการยังอยู่หลังรีโหลด แล้วจึงส่ง:
const n = await db.notifications.create({ userId, title: 'Ann replied to your comment', url: '/posts/42#c7' });
await pusher.sendToUser(String(userId), 'notification', { id: n.id, title: n.title, url: n.url });sendToUser หนึ่งครั้งไปถึงทุกแท็บและทุกอุปกรณ์ของผู้ใช้ และนับเป็นหนึ่งข้อความ ไม่ว่าจะมีกี่ซ็อกเก็ตที่ได้รับ
ขั้นที่ 3: ใช้พุชแทนเมื่อผู้ใช้ออฟไลน์
ให้ทุกหน้าที่ลงชื่อเข้าใช้แล้วสมัครรับช่องส่วนตัว เช่น private-user-42 และให้ endpoint ของ webhook รับ channel_occupied กับ channel_vacated เซิร์ฟเวอร์ของคุณก็จะรู้ว่าใครออนไลน์อยู่โดยไม่ต้องถาม:
app.post('/pusher/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
const webhook = pusher.webhook({ headers: req.headers, rawBody: req.body.toString() });
if (!webhook.isValid()) return res.sendStatus(401);
for (const e of webhook.getEvents()) {
const id = e.channel.match(/^private-user-(.+)$/)?.[1];
if (id) await db.users.update(id, { online: e.name === 'channel_occupied' });
}
res.sendStatus(200);
});เมื่อผู้ใช้ออฟไลน์ ให้ส่งไปยังอุปกรณ์ของเขาตามคู่มือการแจ้งเตือนแบบพุช:
if (!(await db.users.isOnline(userId))) {
await beams.publishToUsers([String(userId)], {
web: { notification: { title: n.title, deep_link: 'https://your-site.example' + n.url } },
fcm: { notification: { title: n.title } },
apns: { aps: { alert: { title: n.title } } },
});
}เคล็ดลับ
- ให้ข้อมูลที่ส่งมีขนาดเล็ก (ID ชื่อเรื่อง และลิงก์) แล้วค่อยโหลดรายละเอียดเมื่อผู้ใช้เปิดดู อีเวนต์มีขนาดได้ไม่เกิน 10 KB (แผน Free 4 KB)
- ทำเครื่องหมายว่าอ่านแล้วบนเซิร์ฟเวอร์และส่งอีเวนต์
notifications-readป้ายตัวเลขจะหายไปพร้อมกันทุกแท็บ - ข้อมูลสุขภาพ การเงิน หรือบุคคล ให้ส่งไปที่ช่อง
private-encrypted-user-42แทน Hibira ส่งต่อเพียงข้อความที่เข้ารหัสแล้ว - ในแผน Free ให้เพิ่มโดเมนของเว็บไซต์เป็นต้นทางที่อนุญาตในการตั้งค่าแอป