更新时间:2022-01-08 22:05:22
您的问题的答案很简单:您需要一种方法来识别谁是谁.这不是 socket.id
因为它只识别套接字,而不是用户,正如您已经注意到的那样.
The answer to your question is quite simple: you need a way to identify who is who. And that is not socket.id
because this only identifies sockets, not users, as you've already noticed.
所以你需要一些认证机制.一旦用户通过身份验证,您就可以重用他的真实 id(无论它是数据库中的简单名称还是整数都无关紧要).然后在服务器端,您保留一组对 (true_id, socket_id)
.每当有消息到达该用户时,您就将其广播给所有匹配的 socket.io 对象.
So you need some authentication mechanism. Once a user authenticates you can reuse his true id (whether it is simply a name or an integer in a database is irrelevant). And then on the server side you keep a collection of pairs (true_id, socket_id)
. And whenever a message comes to that user, you broadcast it to all matched socket.io objects.
流程如下:
true_id
,客户端将其存储在某处.客户端还可以存储一些 session_id
或其他一些机制,允许他在断开连接的情况下快速重新进行身份验证(注意:不要存储凭据,这是一个安全问题).(true_id,socket_id)
对(这是一个实现细节,这里应该使用什么样的数据结构,可能两个{}
对象就足够了).如果连接终止,则删除 (true_id, socket_id)
条目.请注意,对于给定的 true_id
,可能还有其他一些 socket_id
活着.所以这并不意味着用户断开连接.这仅意味着此特定频道已死.socket_id
,他们只关心true_id
.你发出的是 {target_id: true_id, ...}
而不是 {target_id: socket_id, ...}
在客户端,当你想直接发送消息.true_id
的消息时,它检索所有 (true_id, socket_id)
对并将消息传递给 all这些套接字(注意:也许你甚至不需要 socket_id
,你可以简单地在这里存储 socket
对象).虽然这是一个业务逻辑:你允许每个用户有多个连接吗?我会.这里有很多边缘情况(例如客户端认为他断开连接,但服务器认为他仍然连接等)并且不幸的是不可能做到 100% 正确(由于网络的性质).但是只要稍加努力,就有可能让它在 99% 的时间里都能正常工作.true_id
的新 socket_id
.true_id
, which the client stores somewhere. The client may also store some session_id
or maybe some other mechanism that will allow him fast reauthentication in case of disconnection (note: do not store credentials, its a security issue).(true_id, socket_id)
pairs in the form of a double way, mutlivalue map (it's an implementation detail what kind of data structure should be used here, maybe two {}
objects is enough). If a connection dies then (true_id, socket_id)
entry is removed. Note that for a given true_id
there still may be some other socket_id
alive. And so it doesn't mean that the user disconnected. It only means that this particular channel is dead.socket_id
, they only care about true_id
. What you emit is {target_id: true_id, ...}
instead of {target_id: socket_id, ...}
on the client side, when you want to send a direct message.true_id
inside, it retrieves all (true_id, socket_id)
pairs and passes the message to all of these sockets (note: maybe you don't even need socket_id
, you can simply store socket
objects here). Although this is a business logic: do you allow multiple connections per user? I would. There are many edge cases here (like for example a client thinks that he disconnected, but the server thinks he is still connected, etc) and making this 100% correct is unfortunately impossible (due to the nature of networking). But with a bit of effort it is possible to make it work 99% of the time.socket_id
for old true_id
is generated on the server side.让我再次强调这一点:客户端根本不关心 socket_id
.因为那不能识别它们.这仅标识一个频道.并且只有服务器关心这些信息.
Let me emphasize this again: clients don't care about socket_id
at all. Because that doesn't identify them. This only identifies a channel. And only the server cares about this information.