Momentoで構築する: インスタントメッセージ

インスタントメッセージが必要だけど、何から始めたらいいかわからない?お任せください。

初めてインスタントメッセージクライアントを使ったのは、2001年のAOLインスタントメッセンジャーでした。当時は、学校の友達とチャットできるなんて魔法のように感じたものです。今思えば、かなり革命的で、ソフトウェアとの付き合い方やコミュニケーションのあり方を形作る上で大きな役割を果たしました。今日、インスタントメッセージングは、ソーシャルメディアやゲームからカスタマーサポートやヘルスケアに至るまで、数多くのアプリケーションに不可欠な要素となっています。しかし、効率的なインスタントメッセージングシステムを開発することは、非常に難しいことです。

初めてインスタント・メッセージングを作ったときは、あまりにオーバーエンジニアリングでした。REST APIでメッセージを送信し、そのメッセージをデータベースに保存した後、メッセージング・サービスにイベントを発行しました。メッセージング・サービスはルームIDを見てイベントに応答し、そのルームにリンクされているコネクションにWebSocket経由でメッセージをプッシュしました。

インスタント・メッセージというより、”スピーディーな “メッセージングに近い構成でした。

インスタント・メッセージング機能はシンプルであるべです。WebSocketサーバーと一時的なデータストアの2つだけです。誰かがチャットルームに接続したら、チャット履歴をすべて取り出し、新しい接続に送信します。誰かがメッセージを送ったら、そのメッセージを一時データストアにプッシュし、ルーム内の他のすべての接続に送信します。

コンプライアンス上の理由で必要であったり、Slackのような長持ちし、耐久性のあるチャットアプリケーションを構築していない限り、チャットメッセージは保持する必要はありません。セッションベースのチャットは短命であり、10分の1程度です。チャットが終了したら、すべてのメッセージを削除しましょう。ゲーム内チャットのように、長持ちしないものの保存にお金を払う必要はありません。

産業分野

インスタント・メッセージは、リアルタイム・コミュニケーションに依存する以下のような幅広い業界で定番となっています:

1.カスタマ サポート: ライブチャットサポートシステムの応答時間を改善し、顧客にシームレスなエクスペリエンスを提供します。
2.コラボレーションツール: プロジェクト管理ツールや共有ワークスペースでリアルタイムのコミュニケーションを促進し、チーム内のコラボレーションを強化します。
3.ゲーム :プレイヤー間の低遅延通信を必要とするゲーム内のチャットやメッセージングシステムを有効にします。
4.ソーシャルメディア :ソーシャルネットワーキングプラットフォームのインスタントメッセージ機能を強化し、ユーザーが遅延なくチャットできるようにします。
5.ヘルスケア : 医療従事者と患者間の安全でリアルタイムなコミュニケーションを促進します。

Momentoが最適な理由

Momento Cacheのような一時的なデータストアを使用すると、いくつかの利点があります:

1.パフォーマンス: メッセージをキャッシュに保存することで、Momento Cacheは応答時間を短縮し、ユーザーがほぼ瞬時にメッセージにアクセスできるようにします。
2.スケーラビリティ: サーバーレス・ソリューションであるMomento Cacheは、トラフィックの変動に合わせて自動的にスケーリングし、小規模なアプリケーションから大規模なアプリケーションまで対応します。
3.コスト効率: 従量課金モデルにより、Momento Cacheは高額なインフラ投資を不要にし、継続的なメンテナンスコストを削減します。
4.セキュリティ : Momento Cacheはメッセージを一時的に保存し、機密データへの不正アクセスのリスクを最小限に抑えます。
5.柔軟性: Momento Cacheは、さまざまなメッセージング・プロトコルやプラットフォームとシームレスに統合されているため、特定のユースケースに簡単に適合させることができます。
6.自動期限切れ: Momentoに送信されるすべてのデータには、TTL(Time To Live)が設定されています。TTLが切れると、データは永久に削除されます。自分で後始末をする必要はありません。

アプリケーションの例

Socket.ioとMomento Node.js SDKを使用した以下の例をご覧ください。


const http = require('http');
const socketIO = require('socket.io');
const dotenv = require('dotenv');
const { CacheClient, Configurations, CredentialProvider } = require('@gomomento/sdk');

dotenv.config();

const server = http.createServer();
const io = socketIO(server, { cors: { origin: '*', methods: ['GET', 'POST'] } });
const cacheClient = new CacheClient({
    configuration: Configurations.Laptop.latest(),
    credentialProvider: CredentialProvider.fromEnvironmentVariable({ environmentVariableName: 'AUTH_TOKEN' }),
    defaultTtlSeconds: 3600 // 1 hour chat history
})

io.on('connection', (socket) => {
    // User joined a chat room
    socket.on('join', async ({ room }) => {
        socket.join(room);

        let chatHistory = [];
        const response = await cacheClient.listFetch('chat', room);
        if (!response.is_miss) {
            chatHistory = response.valueListString().map(m => JSON.parse(m));
        }

        socket.emit('joined', { chatHistory });
    });

    // Message handler
    socket.on('message', async ({ room, message, name }) => {
        const chatMessage = JSON.stringify({ username: name ?? socket.id, message });

        // Broadcast the message to all connected clients in the room, including the person who sent it
        io.to(room).emit('message', { chatMessage });

        await cacheClient.listPushBack('chat', room, chatMessage);
    });

    // Leave a chat room
    socket.on('leave', ({ room }) => {
        socket.leave(room);
    });

    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
    });
});

server.listen(3000, () => {
    console.log(`Server running on port 3000`);
});

フロントエンドでこのウェブソケットに接続してやりとりするには、socket.ioクライアントを使用してバックエンドと通信するシンプルなhtmlページを作成します。チャットアプリのクライアント側のスクリプトを見てみましょう。

const socket = io('http://localhost:3000');

const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const messages = document.getElementById('messages');
const userInfo = document.getElementById('user-info');
let name;
let query = window.location.href.split('?');
if (query.length == 2) {
    name = query[1].split('=')[1];
}

socket.on('connect', () => {
    console.log('Connected to the server');
    if (!name) {
        name = socket.id;
    }
    userInfo.textContent = `You are logged in as ${name}`;
});

socket.on('message', (data) => {
    const message = JSON.parse(data.chatMessage);
    const li = document.createElement('li');

    const usernameStrong = document.createElement('strong');
    usernameStrong.textContent = `${message.username}: `;
    li.appendChild(usernameStrong);

    const messageText = document.createTextNode(message.message);
    li.appendChild(messageText);

    if (message.username == name) {
        li.classList.add('my-message');
    }

    messages.appendChild(li);
});

socket.on('joined', (data) => {
    for (const message of data.chatHistory) {
        const li = document.createElement('li');

        const usernameStrong = document.createElement('strong');
        usernameStrong.textContent = `${message.username}: `;
        li.appendChild(usernameStrong);

        const messageText = document.createTextNode(message.message);
        li.appendChild(messageText);

        if (message.username == socket.id) {
            li.classList.add('my-message');
        }
        messages.appendChild(li);
    }
});

クライアント側の完全な実装については、ソースコードを参照してください。

ユーザーがチャットルームに接続すると、参加ソケットメッセージがサーバーサイドのコードをトリガーして、Momentoのリストからすべてのメッセージを読み込みます。リストを使って、メッセージが送信された順番を自動的に保持します。

メッセージが送信されると、ソケットはonMessageイベントを受け取り、ユーザー名とメッセージをMomentoリストにプッシュし、チャットルームの他のすべての接続に受け渡す。

ベストプラクティス

Momentoでチャットアプリケーションを構築する際には、以下のベストプラクティスに留意してください:
リストを使って、データを取得したのと同じ順序で保存する。
・メタ情報をJSON文字列としてリストに格納する。
・リストのTTLは、イベントの継続時間より少し長めに設定する。たとえば、30分のオンラインゲームのTTLは31分です。カスタマーサポートチャットは、Momentoの最大TTL:24時間ライブでなければなりません。

忘れないでください!

インスタントメッセージは、もはや贅沢品ではなく、ペースの速いデジタル世界では必需品です。ユーザーを引き付け続けたいソーシャルメディア・プラットフォーム、プレーヤー間のリアルタイムのコミュニケーションを促進したいゲーム会社、専門家と患者の間で迅速かつ安全なリアルタイムコミュニケーションを提供する必要がある医療機関など、Momento Cacheはプロセスを簡素化し、強化するソリューションです。

Momentoは、インスタントメッセージングシステム構築の複雑さを軽減し、卓越したユーザーエクスペリエンスの提供という最も重要なことに集中できるようにします。

始める準備はできましたか?Momento Consoleから無料のトークンにサインアップして、お好きなプログラミング言語で私たちのSDKをお使いください!

Happy coding!