web-dev-qa-db-ja.com

socket.ioおよびExpressの設計パターン

Node.js Express RESTful HTTPサーバーをサーバーAと呼び、Express socket.ioサーバーをサーバーBと呼びます。

サーバーAはクライアントによるすべてのHTTPリクエストに応答し、サーバーBはMongoDB oplogをリッスンして、データベースの更新を現在allクライアントに送信します。

すべてのDB更新をallクライアントに送信したくない-サーバーBと接続されたクライアントがサーバーBを分割して特定の/関連するDBのみをロードするようにして、負荷を軽減するようにシステムを最適化したい更新は特定のクライアントに送信されます...このようにして、サーバーBは以前のメッセージの一部のみを送信でき、各クライアントはすべての更新を処理する必要がなくなります。

Socket.ioルームとクライアントが名前空間に参加する方法について少し読んだ。

以前は、特定のユーザーに関連するすべてのMongoDBコレクションにユーザーIDを追加していたため、各クライアントに、ユーザーIDで示される名前空間に参加させることができました。

これは、各クライアントがサーバー上の名前空間に対応する更新と、すべてのユーザーに関連するいくつかのユニバーサル更新のみを取得することを意味する場合があります。

私の質問は、サーバーとクライアントの負荷を最小限に抑えながら、すべてのユーザーが必要な更新を取得できるようにこれを最適に設計する方法です。

MongoDB、MongoDB oplog、および個別のsocket.ioサーバーを使用してこれを最適に行う方法についてアドバイスはありますか?

3
Alexander Mills

これは1年前に尋ねましたが、私には解決策があります!まだsocket.ioを使用している場合に使用できるもの

俳句共有アプリケーションを作成しているときにこの問題に遭遇しましたね( http://haiku.run で確認できます)。

Githubでホストされている私のソースコードは http://github.com/sova/haiku.run で確認できます。

index.jsのコードを確認してください https://github.com/sova/haiku.run/blob/master/src/index.js#L95

行95には次のコードがあります。

clients[clients.indexOf(socket)].emit('load_haiku_from_cache', a_latest_haiku);

基本的に、新しいユーザーが接続するときに、haiku_cacheなどの変数のノードアプリのRAMに保存されている俳句のキャッシュをロードします。7つあります。キャッシュし、ユーザーが新たに接続したときに発行されます。

ただし、新しいユーザー、たとえばユーザー2が接続した場合、ユーザー1は(通常は)ソケットスプラインフィードのキャッシュの二重更新を取得するため、違います。

したがって、上記のコードは1つの特定のソケットに沿って効果的に情報を出力します。

結論として、特定の情報セットを受け取りたいすべてのソケットを追跡し、上記のような行を使用して特定のソケットに送信することをお勧めします。上記の行を使用して、ワイヤ経由/ソケット経由で、特定の接続されたクライアントに放出できます。

Group/roomのsocket.ioはやや乱雑なので、「接続されたピアのサブセットにエミットする方法」の良い解決策を探している人を助けてくれることを願っています。

1
sova