How Web Push Notifications Work Internally

新着メッセージ、注文の更新、支払いのリマインダーなどの通知を目にすることがあります。

一見シンプルに見えます。バックエンドがメッセージを送信し、ユーザーがそれを受け取るだけです。

しかし実際には、このプロセスには多くの要素が関わっています。バックエンドがブラウザと直接通信することはありません。代わりに、Push Serviceを使用します。

Google ChromeはFirebase Cloud Messagingを使用し、FirefoxはMozilla Push Serviceを使用しています。

ワークフローは以下の通りです:

Backend → Push Service → Browser → Service Worker → User

以下に、ReactとGolangを使用してこのシステムを構築する方法を説明します。

The Components

  1. Frontend (React): 権限をリクエストし、Service Workerを登録します。
  2. Service Worker: ブラウザ内で動作するバックグラウンドスクリプトです。ウェブサイトが閉じられている間でもイベントを処理します。
  3. Backend (Golang): サブスクリプションを保存し、暗号化されたメッセージを送信します。
  4. Push Service: メッセージをブラウザに届ける仲介役です。

The Subscription Flow

メッセージを送信するには、サブスクリプションが必要です。

  • ユーザーが権限を許可します。
  • ブラウザが、エンドポイントとセキュリティキーを含むサブスクリプションオブジェクトを生成します。
  • ReactアプリがこのオブジェクトをGolangバックエンドに送信します。
  • バックエンドがそれをデータベースに保存します。

サーバーを識別するためにVAPIDキーを使用する必要があります。フロントエンドには公開鍵を、バックエンドには秘密鍵を使用してください。秘密鍵は決して共有しないでください。

The Implementation

Reactでは、プッシュイベントをリッスンするためにService Workerを登録します。このワーカーはバックグラウンドで動作し、データを受け取ってユーザーに通知を表示します。

Golangでは、ライブラリを使用して暗号化とVAPID認証を処理します。サーバーはデータベースからサブスクリプションを読み取り、ペイロードを暗号化してブラウザのプッシュサービスに送信します。

Scaling for Production

小規模なプロジェクトであればシンプルな構成で十分ですが、大規模なシステムではさらなる対策が必要です。

  • Handle multiple devices: 1人のユーザーがスマートフォンとノートPCの両方を持っている場合があります。ユーザーごとに複数のサブスクリプションを保存してください。
  • Clean up data: サブスクリプションには有効期限があります。404または410エラーが発生した場合は、そのサブスクリプションをデータベースから削除してください。
  • Use Queues: 数百万人のユーザーを対象とする場合は、Kafkaなどのツールを使用してください。これにより、システムが非同期で通知を処理できるようになります。
  • Implement retries: ネットワーク障害に対処するために、指数バックオフ (exponential backoff) を使用してください。

WebSocketは、ユーザーがアクティブな状態でのライブチャットに適しています。Webプッシュは、タブが閉じられているときにユーザーにリーチするのに適しています。

Source: https://dev.to/chandu_bobbili_06/how-web-push-notifications-work-internally-implementing-with-react-golang-6m