聊天应用程序如何为特定聊天生成一个 id?

Chat application how to generate an id for a particular chat?

假设我有两个用户,"Matt" 和 "Kevin"。 Matt 想给 Kevin 发消息,通过单击聊天按钮向 Kevin 发送直接消息,聊天框会启动,他发送一条消息,Kevin 会收到消息。

我通过将发送消息的人 (Matt) 和接收消息的人 (Kevin) 连接成一个 ID 来生成聊天 ID。

var me = "Matt";
var user = "Kevin";
var uniqueChatID = me+user;

当我保存消息服务器端(使用 mongoDB)时,消息对象的 chatIDMattKevin。所以现在当我想回到那个聊天时,我可以使用 MattKevinchatID 拉入所有消息。

这很好用,直到 Kevin 想启动与 Matt 的聊天,然后 ID 变成 KevinMatt。现在我指的是另一个聊天,它是倒退的。因此,如果我想通过 uniqueChatID 来获取消息,它将拉取不同的集合。

var me = "Kevin";
var user = "Matt";
var uniqueChatID = me+user;

所以我很好奇我怎样才能更好地设置它,以便我的程序知道,好的,Matt 和 Kevin 正在聊天,所以如果 Matt 向 Kevin 发送消息,它会拉入他们的聊天,反之亦然,Kevin 向 Matt 和 Kevin 发送消息它收到相同的消息?

按字母顺序排序:

var me = "Kevin";
var user = "Matt";
var uniqueChatID = [me, user].sort().join('');

也就是说,虽然这在技术上可行,但我建议您做一些内务处理 - 确保它们始终是小写字母,并确保在您的数据库上强制执行唯一的用户名。或者,我什至建议为用户提供一个唯一标识符(如 UUID)并使用 that 来创建 UCID:

var me = CurrentUser.uuid(); // 8cb3ebb8-30f9-11e5-a151-feff819cdc9f
var targetUser = Chat.targetUser(); // Matt: 9bc1ef9c-6719-4041-afd3-c5b87c90690d
var uniqueChatID = [me, targetUser].sort().join(',');
// 8cb3ebb8-30f9-11e5-a151-feff819cdc9f,9bc1ef9c-6719-4041-afd3-c5b87c90690d

最后,如果您的数据库支持关系或连接,您最好的选择是将每个聊天的聊天 table/collection 分开,并在用户和聊天之间 "connect"(或创建关系)。然后下次你去加载它时,连接将引导你进入一个连接到两个用户的独特聊天。

我认为你的方法太复杂了。此外,您似乎想要将单独的聊天消息嵌入包含创建的 _id 的文档中。这里的问题是有一个 16 MB size limit on BSON documents at the time of this writing. Upon reaching this limit, your users simply could not communicate any more. Increasing the size of documents may also lead to frequent document relocations,这是一个 非常 昂贵的操作,除非你使用 MongoDB 的 3.0 版中引入的新的 WiredTiger 存储引擎。

所以我们需要一种更具可扩展性的方法。

我会这样做:

用户:

{
  _id: "Kevin",
  email: "kevin@example.com"
  /* Put further user details as you see fit*/
}

留言:

{
  _id: new ObjectId(),
  from: "Kevin",
  /* You might want to have multi-person chats, hence the array */
  to: ["Matt"],
  ts: new ISODate(),
  message: "Hi, Matt!"
}

索引:

db.messages.ensureIndex({from:1,to:1,ts:1})

重建用户收到的所有消息的查询:

var user = "Matt"
db.messages.find({"to": user}).sort({ts:1})

现在您可以遍历结果集并为找到的每个 "from" 打开一个聊天 window。

重建已定义聊天的查询

var user = "Matt"
var sender = "Kevin"
db.messages.find({"from": sender, "to":user}).sort({ts:1})

将为您提供 Kevin 发送给 Matt 的所有消息,按时间排序。由于两个查询都应使用索引,因此它们应该非常快。您可以使用 .limit(x) 仅查询发送至 user.

的最后 x 条消息

使用这种方法,您不需要人工 _id,创建的索引允许您高效地执行与参与者相关的每个查询,并且消息可以按顺序排序。因为每条消息都是单独保存的并且不再更改,所以您可以存储几乎无限数量的消息并绕过文档重定位问题。