前提・実現したいこと
WebSocketにてアプリケーションサーバーと常時接続しており、
随時リクエストとレスポンスの送受信を行うアプリを開発しています。
アプリケーションのイメージとしては、チャットや掲示板のようなもので、
リアルタイムに書き込み内容が他のクライアントへ反映されます。
クライアントからの書き込みに応じて他のクライアントへのプッシュ通知を行うのですが、
複数サーバー時にすべてのクライアントへプッシュ通知を行うことが実現できていません。
WebSocketにてプッシュ通知を行うアプリにおいて、複数サーバー時にすべてのクライアントへ通知を送信するには、どうすればよいでしょうか。
『接続形態』
・AP Server と Client は WebSocket にて常時接続している。
・AP Server は1台の場合もあれば、複数存在する場合もある。(クライアント数に応じて増設している)
・Client-A1, Client-A2 は AP Server-A に接続している。
・Client-B1, Client-B2 は AP Server-B に接続している。
text
1 +-------------+ 2+-----------+ | AP Server-A | 3| Client-A1 | <- WS -> | | 4+-----------+ | WebSockApp | 5 | | 6+-----------+ | | 7| Client-A2 | <- WS -> | | +-------------+ 8+-----------+ | | <- JDBC -> | DB Server | 9 +-------------+ | | 10 | | 11 +-------------+ | | 12+-----------+ | AP Server-B | <- JDBC -> | | 13| Client-B1 | <- WS -> | | +-------------+ 14+-----------+ | WebSockApp | 15 | | 16+-----------+ | | 17| Client-B2 | <- WS -> | | 18+-----------+ | | 19 +-------------+
実現できていること
・Client-A1 からの情報更新をトリガーにして、AP Server-A に接続している全クライアントへプッシュ通知を行う。
(この場合の通知対象は Client-A1, Client-A2)
・Client-B1 からの情報更新をトリガーにして、AP Server-B に接続している全クライアントへプッシュ通知を行う。
(この場合の通知対象は Client-B1, Client-B2)
発生している問題
・クライアントからの情報更新に応じて、すべての クライアントへプッシュ通知を行いたいが、実現できてない。
(この場合の通知対象は Client-A1, Client-A2, Client-B1, Client-B2)
考察
・AP Server-A からプッシュ通知が送信できるのは、自サーバーに接続しているクライアントのみ。
『理由』
他サーバーに接続しているクライアントにはTCPコネクションが無いし、WebSocketのセッション情報も保持していないため。
試したこと・代替案
・すべてのクライアントが定期的にサーバーへリクエストを発行し、更新されていないかチェックする
→ この方法では無駄にサーバーの負荷が増大する。また、WebSocketを使用している意味が無いため、採用したくない。
・自サーバーに接続していないクライアントへのプッシュ通知要求が発生したときは、
APサーバーから他のAPサーバーへHTTP POST(Servlet等で中継)にてプッシュ通知の送信要求を連携する。
→ この方法ではサーバー数が増えるに従い無駄なPOSTリクエストが発生するため、採用したくない。
・自サーバーに接続していないクライアントへのプッシュ通知要求が発生したときの連携を、他のサーバーへHTTP POST(Servlet等で中継)ではなく
メッセージキューのPub/Subにて実施する。
→ 現在 ActiveMQ + リソースアダプタ + Message-driven Bean にて検証を実施中だが、安定して動作するかが不明。
補足情報(FW/ツールのバージョンなど)
・サーバーのOSは CentOS 8.2
・クライアントのOSは Windows10
・APサーバーのJavaバージョンは OpenJDK 1.8.0_252
・AP Server は GlassFish4系, Payara5系 (WebSocket実装はTyrus)
・Client は C#で自作 (WebSocket実装はwebsocket-sharp)