Thông báo trong ứng dụng theo thời gian thực
Hiển thị phản hồi, lượt nhắc tên và phê duyệt ngay khi chúng xảy ra trên mọi tab đang mở, và chuyển sang thông báo đẩy khi người dùng ngoại tuyến.
Người dùng nhận ra khi sản phẩm phản hồi ngay lúc có chuyện xảy ra: một bình luận trên bài viết của họ, một yêu cầu được duyệt, một lần đồng đội nhắc tên. Cứ 30 giây lại hỏi máy chủ một lần thì vừa chậm vừa tốn yêu cầu. Với Hibira, máy chủ của bạn chỉ gửi thông báo một lần, và mọi tab, mọi thiết bị người dùng đang mở sẽ hiển thị nó trong vài mili giây. Khi họ ngoại tuyến, thông báo đẩy sẽ thay thế.
Người dùng nhận được gì
- Huy hiệu chuông và thông báo nhỏ cập nhật ngay khi có chuyện xảy ra, trên mọi tab đang mở.
- Cùng thông báo đó trên điện thoại khi ứng dụng đang đóng.
- Không cần tải lại để thấy hoạt động mới, và bộ đếm không bị cũ.
Dùng những gì
- Xác thực người dùng (
pusher.signin()), để mỗi người dùng có kênh riêng mà chỉ họ đọc được. sendToUsertrong SDK máy chủ chính thức, tới mọi socket của người dùng đó trên mọi node.- Thông báo đẩy qua API tương thích Beams cho người dùng không kết nối.
- Kênh riêng tư mã hóa (
private-encrypted-) khi thông báo chứa dữ liệu cần mã hóa đầu cuối.
Bước 1: đăng nhập người dùng trên socket
Thêm route xác thực người dùng bên cạnh route cấp quyền kênh. Nó chạy trên máy chủ của bạn và dùng secret của ứng dụng.
// 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);
});Trong trình duyệt, kết nối như trong hướng dẫn JavaScript rồi đăng nhập:
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 });
});Bước 2: gửi từ máy chủ
Lưu thông báo vào cơ sở dữ liệu trước để danh sách vẫn còn sau khi tải lại, rồi mới gửi:
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 });Một lần sendToUser tới mọi tab và thiết bị của người dùng và chỉ tính là một tin nhắn, dù bao nhiêu socket nhận được.
Bước 3: chuyển sang thông báo đẩy khi họ ngoại tuyến
Cho mỗi trang đã đăng nhập đăng ký một kênh riêng tư như private-user-42, và cho endpoint webhook nhận channel_occupied và channel_vacated. Máy chủ của bạn khi đó biết ai đang trực tuyến mà không cần hỏi:
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);
});Khi người dùng ngoại tuyến, gửi tới thiết bị của họ theo hướng dẫn thông báo đẩy:
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 } } },
});
}Mẹo
- Giữ nội dung nhỏ (một ID, một tiêu đề và một liên kết) và tải chi tiết khi người dùng mở ra. Sự kiện tối đa 10 KB (4 KB với gói Free).
- Đánh dấu đã đọc trên máy chủ và gửi sự kiện
notifications-read, để huy hiệu biến mất trên mọi tab cùng lúc. - Với dữ liệu sức khỏe, tài chính hoặc nhân sự, hãy gửi tới kênh
private-encrypted-user-42: Hibira chỉ chuyển tiếp bản mã. - Với gói Free, hãy thêm các tên miền của trang web vào danh sách nguồn được phép trong cài đặt ứng dụng.