Socket IO - 如何让多个管理员用户访问多个 URL 上的多个私人房间

Posted

技术标签:

【中文标题】Socket IO - 如何让多个管理员用户访问多个 URL 上的多个私人房间【英文标题】:Socket IO - How to have Multiple Admin Users to Multiple Private Rooms on Multiple URLs 【发布时间】:2018-09-25 09:18:50 【问题描述】:

我已经搜索了很久很久。我通常熟悉 LAMP 堆栈,所以很抱歉 - 我正在学习 Node,因为我正在尝试构建一个聊天功能 - 类似于 Intercom/drift 的工作方式。

我一直认为 Socket.io 是解决此问题的好方法,但我遇到了一些麻烦。基本概述是这样的:

用户可以使用我的服务在他们的网站上启用实时聊天功能(他们每个人都有一个唯一的 API 密钥) 他们可以将聊天添加到任意数量的网页/域(通过脚本标签) 网站的任何单个最终用户与脚本标签的管理员(用于在页面上包含脚本的 API 密钥的所有者)之间的聊天应该是私密的

我遇到了这个问题。

我应该为每个 URL 创建动态命名空间,还是一个房间?

假设我在客户端创建了一个独特的动态房间,例如在https://***.com/a/19150254/1173155中使用

// client side code
var dynamicRoomName = API_KEY + "_" + fullURL  + "_" + expressSessionId;
var socket = io.connect();
socket.emit('create room', dynamicRoomName);

// server side code
io.sockets.on('connection', function(socket) 
  socket.on('create room', function(room) 
    socket.join(room);
  );
);

除了最终用户之外,唯一应该能够看到此聊天的人是该 API 密钥的管理员,我不确定如何实施。

我意识到我可能需要某种数据库来跟踪聊天/房间等。有没有什么好的资源来学习如何实现这种东西?

非常感谢您的帮助!


只是稍微扩展一下,也许是为了我在解决这个问题时好。

可以有多个管理员(独特的 API) 管理员只负责他们自己的聊天 - 他们看不到任何不属于其 API 密钥的聊天 许多用户可以与一位管理员聊天(私下) 所有聊天都是一对一的 最终用户和管理员用户将因此使用不同的客户端 管理员可以与个人用户进行大量聊天 用户通常会与一位管理员进行一次聊天 管理员无法创建聊天(仅接收来电) - 但当然可以回复

【问题讨论】:

【参考方案1】:

我认为您不想使用命名空间,因为这样您的服务器就必须在服务器上预先侦听每个可能的命名空间才能听到与它的连接。这似乎不切实际且效率低下。有许多不同的可能方案。这是我认为实现起来相当简单的一个。

    您为此管理员聊天创建一个命名空间。 您的服务器侦听该命名空间并接受到它的传入连接。 客户端在需要与管理员聊天时连接到该命名空间。 然后客户端发送一条initiateChat 消息,其中API_KEY 作为数据。 服务器被编码为在收到带有有效 API_KEY 的 initiateChat 之前不接受任何其他消息 当服务器收到initiateChat 消息时,它会在您的数据库中查找 API_KEY,如果它在数据库中找到它并且该用户当前在线,它会与他们开始聊天会话。如果它们当前不可用,它会向客户端发送一条消息,指示它们当前不在线。 现在套接字已为聊天相关消息打开。 如果需要,您可以使用动态创建的房间名称来跟踪两个端点,并将两个套接字连接到该房间。 如果管理员用户可以使用同一个套接字参与多个聊天,那么您必须确保它发送的聊天消息标有它们所属的聊天,以便您知道将消息发送到哪个房间名称您的服务器。

【讨论】:

SocketIO 服务器如何监听动态命名空间,先生? @QuỳnhNguyễn - 不知道你的意思。它需要服务器上的io.of("someNamespace").on("connection", ....) 来监听命名空间。所以,你不能监听一个你不知道名字的命名空间,你必须分别监听每个命名空间。对于有很多东西,命名空间可能是错误的工具。我在回答中描述了一种更好的方式来接受与许多不同的潜在聊天的连接。您是否阅读并理解了我在回答中提出的建议? @QuỳnhNguyễn - 我不认为你理解我的提议。它适用于多个管理员。当您在服务器上收到initiateChat 消息时,您只需使用您的服务器逻辑根据传递的 API_KEY 确定它应该连接到哪个管理员。这比尝试创建大量命名空间侦听器要简单得多。 @shanehoban - 您不需要使用会话 ID。您可以为房间名称创建一个新的唯一 ID。它可能只是一个随机数加上当前日期时间变成一个字符串。然后,您将其传达给管理员,他们将其包含在他们的消息中,让您知道他们正在发送到哪个聊天。对于最终用户,如果他们一次只能在一个聊天中,那么您可以在他们的套接字对象上设置聊天 ID,这样无论何时他们发送消息,您都知道将消息发送到哪个房间。 @shanehoban - 仅供参考,这是一个用于生成唯一 ID 的简单小库:npmjs.com/package/really-unique-id。它结合了随机数、日期时间和计数器,因此 id 始终是唯一的。

以上是关于Socket IO - 如何让多个管理员用户访问多个 URL 上的多个私人房间的主要内容,如果未能解决你的问题,请参考以下文章

在 socket.io 中管理多个选项卡(但同一用户)

39.IO多路复用(用select实现伪并发)

聊天应用 - Socket.io - 我如何向其他用户显示消息?

如何使用 socket.io、react native、nodejs 管理聊天应用程序的多个套接字连接

Socket.io 会话管理?

如何跨多个服务器 nodejs 和 socket.io 存储 socket.id