Momento CacheとTopicsを使ってインスタント・メッセージを構築する
インスタントメッセージングは、多くのアプリケーションで必須の機能です。1対1、1対多、多対多の会話をシームレスに行うことは、多くの場合、アプリケーションに必要なコンポーネントと考えられています。Momento CacheとTopicsを使用すると、バックエンドのインフラストラクチャなしで、アプリケーションにインスタント・メッセージングを組み込むことができます。Momento web SDKを 使用すると、ブラウザで直接キャッシュデータにアクセスし、メッセージを公開および購読できます。
このパターンでは、Momento Cache を使用して過去のメッセージを保存し、Momento Topics を使用してインスタント・メッセージ参加者間のリアルタイム・コミュニケーションを促進します。
アーキテクチャ
Momentoでのインスタントメッセージの構築は、完全にクライアントサイド、つまりユーザーインターフェイスで行うことができます。ブラウザ、iPhoneアプリ、Androidアプリはすべて、Momentoのリソースに直接アクセスする機能を持っています。
上の図では、新しいユーザーがチャットに参加すると、list からメッセージが読み込まれます。ユーザーはチャットルーム固有のトピックを購読し、チャットに参加している間、リアルタイムでメッセージを受け取ります。メッセージが送信されると、送信者によって直接リストに追加されます。
コンポーネント
インスタントメッセージは2つの部分に分かれています:
- Message storage
- Delivery
これらのコアコンポーネントにより、ユーザーはいつでもチャットに参加し、メッセージ履歴を閲覧したり、新しいメッセージをリアルタイムで受信することができます。
Message storage
ほとんどのインスタントメッセージプラットフォームは、ユーザーが到着する前にメッセージが送信された場合、会話の履歴を表示できるようにメッセージを保存します。チャットルームに入るときのスタートアップタスクの一部は、この履歴をロードして画面に表示することです。これはMomentoのlistキャッシュアイテムで簡単にできます。
Lists
リスト は、要素の順序付き配列を格納するコレクション・データ型です。要素をリストの前面または背面にプッシュすることができ、一度に複数のエントリを追加できます。リストは、メッセージが送信された順に格納されるため、インスタント メッセージングに最適なデータ型です。ユーザがインスタントメッセージングセッションに参加すると、1回のlistFetch APIコールでチャット履歴全体をすばやく取得できます。
リスト内の要素は一意である必要はありません。同じメッセージを何度もリストにプッシュすれば、その都度追加されます。リストは、次のような用途のインスタントメッセージに適しています:
- 一度に N 個のメッセージを取得
- 一度に複数のメッセージを追加
- 一定の長さのチャット履歴、つまり直近の100メッセージの保持
リストを使用する場合、多くの配列操作関数があり、メッセージ履歴が長くなりすぎた場合に自動的に切り詰めたり、コンテンツモデレーションなどのために特定の要素を削除したりすることができます。
Delivery
技術的には、メッセージの保存はインスタントメッセージングの必須コンポーネントではありません。理論的には、ユーザーが接続している間に送信されたメッセージだけを表示するメッセージングシステムを持つことができます。メッセージはクライアントのメモリーに保存しておけばよい。対照的に、メッセージ配信はインスタントメッセージングの必須部分です。メッセージを送信者からすべての受信者に最小限の待ち時間で届けることが、このパターンの核心です。これを行うために、Momento Topicsを使います。
Momento Topicsは、クライアント同士、クライアントとサーバー、サーバーとクライアント、サーバーとサーバーを接続する低レイテンシーのPub/Subサービスです。WebSocketのようなものです。トピックにメッセージをパブリッシュすると、Momentoはトピックのすべてのサブスクライバにブロードキャストします。
インスタントメッセージングの場合、送信者はトピックにメッセージを 発行 します。メッセージの受信者は、ユースケースによって1人または多数になりますが、サブスクライバになります。Momento Topicsは、公開されたメッセージをリアルタイムで購読者に配信し、私たちが求めているインスタント・メッセージング体験を提供します!
Momento トピックは、インフラストラクチャのリソースとして定義されていない、柔軟で動的なトピックを提供します。インスタントメッセージングを構築する推奨の方法は、チャットルームまたはセッション識別子をトピック名として使用することです。これにより、チャットのユースケースに柔軟で専用のトピックが提供されます。
メッセージの発行
メッセージを公開するために必要なのは、たったひとつのコマンドだけです:
- Node.js
- Python
- Go
- Java
- .NET
await topics.publish('message-namespace', sessionId, 'Hello world!');
topics.publish("message-namespace", sessionId, "Hello world!")
_, err := topics.Publish(ctx, &momento.TopicPublishRequest{
CacheName: momento.String("message-namespace"),
TopicName: sessionId,
Value: momento.String("Hello world!")
})
final TopicPublishResponse response = topics.publish("message-namespace", sessionId, "Hello world!").join();
var response = await topics.PublishAsync("message-namespace", sessionId, "Hello world!");
トピックの購読
メッセージの購読は、特定のトピックに何かが公開されるたびに、Momentoにそれを配信し、特定のイベントハンドラ関数を実行するように指示します。個々のトピックに対して、1 から数千 (あるいはそれ以上!) のクライアントを購読することができます。
- Node.js
- Python
- Go
- Java
- .NET
const subscription = await topics.subscribe('message-namespace', sessionId, {
onItem: (data) => processMessage(data.value(), data.tokenId())
});
with TopicClient(TopicConfigurations.Default.v1(), _AUTH_PROVIDER) as client:
subscription = client.subscribe("cache", "my_topic")
match subscription:
case TopicSubscribe.Error():
raise Exception("Subscription error: ", subscription.message)
case TopicSubscribe.Subscription():
for item in subscription:
match item:
case TopicSubscriptionItem.Text():
print(item.value)
case TopicSubscriptionItem.Binary():
print(item.value!r)