メインコンテンツへスキップ

概要

Daemon WebSocket API は、Daemon クライアントがリアルタイムでメッセージを受信・処理するための永続的な双方向接続を提供します。クライアントがポーリングする REST API とは異なり、WebSocket 接続により Shannon は受信メッセージ(Slack、LINE、またはシステムイベントから)を接続済みの Daemon に直接プッシュできます。 このプロトコルの中核は Claim ベースのメッセージディスパッチモデルです。Shannon は対象となるすべての接続にメッセージをブロードキャストし、Daemon が排他的処理権を競い合ってから応答します。

エンドポイント

標準の認証 ヘッダー を使用して WebSocket にアップグレードします。

認証

認証は WebSocket アップグレードの前に、REST Endpoint と同じミドルウェアで実行されます。

接続ライフサイクル

1

HTTP アップグレード

クライアントが認証 ヘッダー 付きで GET /v1/ws/messages を送信します。サーバーは資格情報を検証してからアップグレードを行います。
2

WebSocket 確立

サーバーが WebSocket にアップグレードします(gorilla/websocket、4KB 読み書きバッファ、CheckOrigin はすべてのオリジンを許可)。
3

接続確認

サーバーが connected メッセージを送信して、接続の準備完了を確認します。
4

双方向メッセージング

双方が JSON メッセージを交換します。サーバーが受信メッセージをディスパッチし、クライアントが Claim、処理、応答を行います。
5

キープアライブ

サーバーは 20 秒ごとに WebSocket Ping を送信します。クライアントは 60 秒以内に Pong で応答する必要があり、応答がない場合は接続が切断されます。

接続パラメータ

メッセージエンベロープ

すべてのメッセージ(双方向)は統一されたエンベロープ形式に従います:

サーバーからクライアントへのメッセージ

connected

WebSocket 接続の確立直後に一度だけ送信されます。

message

処理のためにディスパッチされたインバウンドメッセージ。これは主要なメッセージタイプで、Channel Webhook(Slack、LINE)またはシステムイベントからのメッセージを伝達します。

MessagePayload フィールド

system

Shannon からのシステムレベル通知。

claim_ack

クライアントの claim リクエストへの応答。Claim が許可されたかどうかを示します。

クライアントからサーバーへのメッセージ

claim

メッセージの排他的処理権を要求します。同一メッセージを Claim できるのは 1 つのクライアントのみです。

progress

Claim 済みメッセージの処理中にハートビート/進捗更新を送信します。Claim のリースが延長され、タイムアウトを防ぎます。

reply

Claim 済みメッセージの処理結果を送信します。Shannon はこれを送信元 Channel(Slack、LINE など)にルーティングします。

ReplyPayload フィールド

disconnect

接続をグレースフルに閉じます。

Claim フロー

Claim フローは分散メッセージ処理の中核プロトコルです。複数の Daemon が接続されていても、各メッセージが 1 つの Daemon のみで処理されることを保証します。
1

メッセージディスパッチ

メッセージが到着すると(Channel Webhook またはシステム経由)、Gateway は tenant:user でインデックスされたすべての対象 WebSocket 接続にメッセージをディスパッチします。
2

Claim 競争

メッセージを処理したい各 Daemon が message_id を含む claim リクエストを送信します。
3

アトミック解決

Gateway が Redis でアトミックに Claim を実行します(SETNX)。最初のクライアントが獲得し、他のクライアントは {"granted": false} を受信します。
4

メッセージ処理

獲得した Daemon がメッセージを処理します。オプションで progress メッセージを送信して Claim リースを延長し、処理状況を報告できます。
5

応答送信

Daemon が処理結果を含む reply を送信します。Shannon はこれを送信元 Channel にルーティングします。

Claim メタデータ

メッセージが Claim されると、Gateway は Redis にメタデータを保存します(TTL 60 秒):
保留中メッセージのメタデータの TTL は 90 秒です。Claim 済みメッセージが 60 秒以内に応答されない場合、Claim は期限切れとなり、メッセージは再ディスパッチの対象となります。

Hub アーキテクチャ

WebSocket Hub はすべてのアクティブな接続を管理し、以下のルーティング戦略を採用しています:
  • Tenant-User インデックス — 接続は "tenant:user" キーでインデックスされ、ターゲットディスパッチを実現
  • スレッドスティッキールーティング — 同一スレッド("channel_type:thread_id")からのメッセージは可能な限り同じ接続にルーティング
  • Redis バックドの Claim — 分散 Claim 解決により、複数の Gateway インスタンス間の一貫性を確保

応答ルーティング

Gateway が Daemon から reply を受信すると、Claim メタデータに基づいて応答をルーティングします:
  1. Workflow 応答 — Claim メタデータに workflow_id が存在する場合、Gateway は関連する Temporal Workflow に Signal で通知します
  2. Channel 応答 — それ以外の場合、応答は送信元 Channel にルーティングされます(Slack メッセージ、LINE Push メッセージなど)

エラーハンドリング

次のステップ

Channels API

Slack と LINE の Channel 統合を管理

ストリーミング

Server-Sent Events によるタスクストリーミング