套接字.io:如何处理打开两个窗口的认证客户端

Socket.io: How to deal with an authenticated client who opens two windows?

本文关键字:两个 窗口 客户端 认证 何处理 io 套接字 处理      更新时间:2023-09-26

我正在编写一个HTML5游戏服务器。服务器包含一个比赛列表,当用户加入其中一个比赛时,他们能够看到游戏的进度,以及与其他用户聊天等。

当用户加入匹配时,服务器在他们的会话对象中查找'userid'字符串。userid字符串是一个用户对象。如果没有找到,则创建一个新的用户对象,并将'userid'字符串添加到会话对象中。

这允许用户使用多个选项卡/窗口连接多个游戏,同时仍然显示相同的用户名,在每个窗口显示图片。

现在的问题是处理同一个用户多次连接到同一个匹配。如果用户有两个窗口连接到同一款游戏,我希望他们在两个窗口上看到完全相同的东西——有点像Facebook聊天。

当前,当用户连接到一个匹配时,一个新的"连接"对象被创建,在这个对象上我处理套接字事件等。

我希望能够做的是使用相同的事件处理函数来处理多个套接字的事件。唯一阻止我的是套接字事件没有"所有者"参数。由于没有引用接收消息的套接字,我不能将消息广播到除了接收消息的套接字之外的所有套接字。

SocketIO Rooms也不符合我的要求,因为通道上没有接收消息的事件。

我被迫考虑的是同时拥有一个连接对象和一个参与者对象,其中每个参与者都有多个连接。我觉得这个很臃肿。

另一种选择是尝试强迫自己使用意大利面条式代码编写,并利用闭包等。

真的需要一些有类似情况的人的建议。

Productish解决方案:强制用户使用一个窗口

如果用户已经连接,并且服务器知道这一点,让第二个窗口显示一个对话框,如

你已经用AwesomeGame打开了另一个窗口。请使用该窗口或点击下面的按钮。

使用此窗口

如果用户单击该按钮,则通过SocketIO发送消息,声明该连接代表该用户。然后,服务器将通知所有先前的连接已被取代。

工程解决方案:为每个客户端提供一个令牌,它们可以使用SocketIO对服务器进行身份验证。

生成并提供HTML时,在页面上包含用户的ID,并用服务器知道的密钥对其签名。例如,我们的标记看起来像:

<user id>|<salt>|<SHA1 hash of uid + salt + secret key>

当客户端连接时,忽略所有消息,直到客户端通过提供签名令牌进行身份验证。服务器可以分解令牌并验证SocketIO客户端确实代表该用户。

在服务器上,使用pubsub系统订阅带有用户id的开放SocketIO连接。当消息绑定到特定用户时,将其发布到用户ID。