メインコンテンツにスキップします

プライベートメッセージ - 第3部

このガイドは4つの異なる部分からなります

  • 第1部:初期実装
  • 第2部:永続的なユーザーID
  • 第3部(現在):永続的なメッセージ
  • 第4部:スケールアップ

第2部の最後に、私たちは以下の状況に直面していました

Chat (v2)

すべてがかなりうまく機能していますが、非常に厄介な最後の問題が1つあります

  • 送信者が切断されると、送信するすべてのパケットは再接続されるまで(この場合、非常に優れています)バッファリングされます
Chat with sender that gets disconnected
  • ただし、受信者が切断されると、指定されたルーム内でリッスンするソケットインスタンスがないため、パケットが失われます
Chat with recipient that gets disconnected

この問題には複数の解決策がありますが、私たちは最も簡単に実装できるものを使用します:すべてのメッセージをサーバー側で保存します。

注意:この第3部は簡潔になりますが、Socket.IOの重要な特性の1つを強調しています。つまり、接続のステータスに依存することはできません。ほとんどの時間は稼働しているはずですが、TCP接続を停止する可能性のある無数のものがあります(これは特にモバイルブラウザに当てはまります)。

インストール

では、第3部のブランチをチェックしてみましょう

git checkout examples/private-messaging-part-3

現在のディレクトリには以下が表示されているはずです

├── babel.config.js
├── package.json
├── public
│ ├── favicon.ico
│ ├── fonts
│ │ └── Lato-Regular.ttf
│ └── index.html
├── README.md
├── server
│ ├── index.js (updated)
│ ├── messageStore.js (created)
│ ├── package.json
│ └── sessionStore.js
└── src
├── App.vue
├── components
│ ├── Chat.vue (updated)
│ ├── MessagePanel.vue
│ ├── SelectUsername.vue
│ ├── StatusIcon.vue
│ └── User.vue
├── main.js
└── socket.js

完全なdiffはこちらにあります。

仕組み

永続的なメッセージ

サーバー側(server/index.js)では、新しいストアにメッセージを永続的に保存します

io.on("connection", (socket) => {
// ...
socket.on("private message", ({ content, to }) => {
const message = {
content,
from: socket.userID,
to,
};
socket.to(to).to(socket.userID).emit("private message", message);
messageStore.saveMessage(message);
});
// ...
});

そして、接続時にメッセージのリストを取得します

io.on("connection", (socket) => {
// ...
const users = [];
const messagesPerUser = new Map();
messageStore.findMessagesForUser(socket.userID).forEach((message) => {
const { from, to } = message;
const otherUser = socket.userID === from ? to : from;
if (messagesPerUser.has(otherUser)) {
messagesPerUser.get(otherUser).push(message);
} else {
messagesPerUser.set(otherUser, [message]);
}
});
sessionStore.findAllSessions().forEach((session) => {
users.push({
userID: session.userID,
username: session.username,
connected: session.connected,
messages: messagesPerUser.get(session.userID) || [],
});
});
socket.emit("users", users);
// ...
});

コードはかなり単純です。これ以上切断時にメッセージを失うことはありません

Chat (v3)

レビュー

機能するチャットができましたので、このガイドの第4部では、複数のSocket.IOサーバーにスケールする方法について説明します。

お読みいただきありがとうございます!