Cách thức hoạt động nội bộ của Web Push Notifications
Bạn thấy các thông báo về tin nhắn mới, cập nhật đơn hàng hoặc nhắc nhở thanh toán.
Trông có vẻ đơn giản. Backend của bạn gửi một tin nhắn và người dùng nhận được nó.
Trên thực tế, quy trình này bao gồm nhiều thành phần chuyển động. Backend của bạn không bao giờ giao tiếp trực tiếp với trình duyệt. Thay vào đó, nó sử dụng một Push Service.
Google Chrome sử dụng Firebase Cloud Messaging. Firefox sử dụng Mozilla Push Service.
Quy trình hoạt động như sau:
Backend → Push Service → Trình duyệt → Service Worker → Người dùng
Dưới đây là cách bạn xây dựng hệ thống này bằng React và Golang.
Các thành phần
- Frontend (React): Yêu cầu quyền và đăng ký một Service Worker.
- Service Worker: Một tập lệnh chạy ngầm trong trình duyệt. Nó xử lý các sự kiện ngay cả khi trang web của bạn đã đóng.
- Backend (Golang): Lưu trữ các đăng ký (subscriptions) và gửi các tin nhắn đã được mã hóa.
- Push Service: Bên trung gian chuyển tin nhắn đến trình duyệt.
Quy trình Đăng ký (Subscription Flow)
Để gửi một tin nhắn, bạn cần một đăng ký (subscription).
- Người dùng cấp quyền.
- Trình duyệt tạo ra một đối tượng đăng ký (subscription object) chứa một endpoint và các khóa bảo mật.
- Ứng dụng React của bạn gửi đối tượng này đến backend Golang.
- Backend của bạn lưu nó vào cơ sở dữ liệu.
Bạn phải sử dụng các khóa VAPID để định danh máy chủ của mình. Sử dụng khóa công khai (public key) cho frontend và khóa riêng tư (private key) cho backend. Đừng bao giờ chia sẻ khóa riêng tư của bạn.
Triển khai
Trong React, bạn đăng ký một Service Worker để lắng nghe các sự kiện push. Worker này chạy ngầm. Nó nhận dữ liệu và hiển thị thông báo cho người dùng.
Trong Golang, bạn sử dụng một thư viện để xử lý mã hóa và xác thực VAPID. Máy chủ của bạn đọc thông tin đăng ký từ cơ sở dữ liệu, mã hóa payload và gửi nó đến dịch vụ push của trình duyệt.
Mở rộng cho môi trường Production
Một thiết lập đơn giản sẽ hoạt động cho các dự án nhỏ. Một hệ thống lớn cần nhiều hơn thế.
- Xử lý nhiều thiết bị: Một người dùng có thể có cả điện thoại và máy tính xách tay. Hãy lưu trữ nhiều đăng ký cho mỗi người dùng.
- Dọn dẹp dữ liệu: Các đăng ký sẽ hết hạn. Nếu bạn nhận được lỗi 404 hoặc 410, hãy xóa đăng ký đó khỏi cơ sở dữ liệu của bạn.
- Sử dụng Hàng đợi (Queues): Đối với hàng triệu người dùng, hãy sử dụng Kafka hoặc một công cụ tương tự. Điều này cho phép hệ thống của bạn xử lý các thông báo một cách bất đồng bộ.
- Triển khai cơ chế thử lại (retries): Sử dụng exponential backoff để xử lý các lỗi mạng.
WebSockets rất tốt cho các cuộc trò chuyện trực tiếp khi người dùng đang hoạt động. Web Push tốt hơn để tiếp cận người dùng khi tab đã đóng.
