私はここで少し岐路に立っているので、コミュニティの意見を聞きたいと思いました。
弊社用のチャットアプリを作成しています。これで、他のすべてのチャットアプリケーションと同様に、メッセージはサーバーに保存され、クライアントは後で古いメッセージにアクセスできるようになります。
私が迷っているのは、特定の状況でHTTP
とWebSocket
を一緒に使用することです。私はすでにそれらを使用しています、完全にうまく、すべてがスムーズに実行されています。私の現在のデザインの選択はこれです:
WebSocket
を介してnew message
イベントをメッセージペイロードとともにサーバーに送信しますnew message
イベントを受信しますasync
サーバーにmongodb
呼び出しを行います。async
呼び出しを行うと、提供されたメッセージとともに他のクライアントにソケットイベントも送信します。私が見ている問題は、DBへのasync
呼び出しが失敗し、DBが実際にメッセージを保存しない場合はどうなるかということです。クライアントはメッセージを受け取る場合がありますが、ログアウトして再度ログインすると、メッセージはDBに保存されなかったため、会話に存在しなくなります。
幸いなことに、これはテストでは発生していませんが、世界中ですべてのテストを実行できることは誰もが知っています。どういうわけか何かが壊れます。この問題について考えている間、私は問題の新しい解決策を思いつきました:
POST
リクエストを送信しますPOST
リクエストを受信しますasync
を指定してawait
呼び出しを行いますすべてのメッセージでHTTP
呼び出しを行う場合と比較して、メッセージが前後に送信されるため、持続的接続を維持することでオーバーヘッドが少なくなることを知っていますが、HTTP
呼び出しにより、クライアントはメッセージを確認できます。実際に送信され、保存されます。
これで、async/await
を使用して元のアイデアを新しいアイデアに変換できます。失敗した場合は、メッセージをまったく送信しないでください。 error
として出力する新しいソケットイベントを作成すると、クライアントはそれに応じてそれを表示します。
どちらが良いか判断できないので、これらの方法の1つが優れているかどうか、またはこの特定のアプリケーション設計にさらに優れたオプションがあるかどうかを尋ねたいと思いました。
ありがとう!
両方を組み合わせます。つまり、3番目のオプションです。 WebSocketメッセージを保持しますが、クライアントに通知する前にデータベースの結果を待つことにより、操作の順序を順番に並べます。
擬似コード:
function on_new_message(sender, msg):
is_duplicate = await save_message_in_db_async(msg)
// If this fails, catch the exception in some error handler.
// The client could also retry
// if they don't receive a reply within some timeout.
// The DB can tell you whether this is a duplicate message.
// At this point the message is saved.
// new clients that join can load it from the DB
sender_notification_future = notify_client_async(sender, {
"type": "message_acknowledged",
"msg_id": msg.id,
})
client_notification_futures = []
if !is_duplicate:
for client in connected_clients:
if client != sender:
client_notification_futures.Push(
notify_client_async(client, msg))
// The order of notifications is not important,
// so await them together
await all(sender_notification_future, client_notification_futures)
または、2番目のオプション(メッセージの送信にPOSTリクエストを使用)を使用する)は、メッセージの送信頻度が低い(最大で数秒に1回)か、HTTPを使用している場合でも問題ありません。/2. POSTリクエストは明確なレスポンスを取得するのに対し、WebSocketはリクエスト/レスポンスのライフサイクルを課さないため、これは簡単かもしれません。コードは基本的に同じですが、送信者にレスポンスする点が異なります。それらに通知を送信する代わりに。