如果使用 Node.js 在 Socket.io 中的应用程序中登录功能,则为特定用户发出事件
Posted
技术标签:
【中文标题】如果使用 Node.js 在 Socket.io 中的应用程序中登录功能,则为特定用户发出事件【英文标题】:Emit event for particular user if login functionality in application in Socket.io with Node.js 【发布时间】:2019-06-07 17:54:37 【问题描述】:我使用了socket.on
和io.emit
方法,我得到了所有用户的响应。但是,我想得到特定用户的响应。
但是我的应用程序包含登录功能,我在 *** 上关注了 this 帖子,他们说 我们需要在一个对象中唯一的 userId
和 socketId
以便特定用户发出特定用户的事件。
但是我在登录后得到了 userId,但是当用户连接到应用程序时我们想要它。
那么任何人都可以帮助我吗?
【问题讨论】:
【参考方案1】:在你的node.js中,创建一个全局数组'aryUser',每个元素都包含socketid和loginid。
node.js onConnect(新连接),用socketid向数组中添加一个新元素并设置loginid = empty。
用户登录后,从客户端向服务器发出一个事件,例如:
socket.emit('userloginok', loginid)
-
在 node.js 中,定义一个函数:
socket.on('userloginok', loginid)
在这个函数中,用socketid搜索aryUser,并用parm loginid替换数组元素中的空loginid。
-
在node.js中,定义函数:
socket.on('断开连接')
在这个函数中,搜索aryUser,使用aryUser.splice(i,1)删除刚刚断开的用户。
这意味着,aryUser 包含所有已连接的用户,其中一些已登录,有些未登录。您可以使用数组的 socketid 向特定用户和/或所有用户发送消息。
示例源代码:
-
server.js
http://www.zephan.top/server.js
-
server.html
http://www.zephan.top/server.html.txt
将server.html.txt重命名为server.html,将server.html和server.js放在同一目录下,运行:
节点服务器.js
【讨论】:
感谢您的快速回复。你的答案看起来不错,但我没有得到一件事。 “使用 socketid 搜索 aryUser”。我没有明白这一点。你能再解释一下吗? 在node.js中,当你定义了一个函数socket.on('SomeFunctionToBeCalledByClient', SomeDataFromClient),在这个函数内部,有一个‘预定义的,唯一的系统变量’,即:socket。 socketid,它可以帮助您识别哪个客户端实际上正在调用您的函数,因此您可以将此 id 存储到 Global 数组中。 即你可以在 socket.on('connect'/'disconnect'/'anything') 中使用 socket.socketid @KennethLi,你说的第三点。登录后从客户端向服务器发出事件,但是用户如何在客户端获得套接字 ID?因为它仅在服务器上可用。 我现在在用手机,你可以试试这个网站,是我的学生Zephan创建的:thisapp.zephan.top这个网站/app是cordova创建的,是个练习对于我的学生,这是一个类似 Whatsapp 的应用程序。您可以通过注册自己的用户 id 来尝试,或者使用测试 id,test1 和 test2,密码:qwerty。【参考方案2】:是的,您肯定需要socketId
才能在两个特定用户之间发送和接收消息。
UserId
仅用于跟踪与特定用户关联的socketId
,或者您也可以通过其他方式对其进行管理,这取决于您。
根据您的问题,您拥有该用户的userId
,并且您需要该用户的socketId
!因此,在这种情况下,您可以在特定从客户端连接到套接字服务器时传递userId
,如下面的 sn-p 所示,
const socket = io(this.SOCKET_SERVER_BASE_URL, query: `userId=$userId` );
你可以像这样在nodejs服务器上读取这个用户,
const userId= socket.request._query['userId'],
const socketId= socket.id
现在将这个socketId
存储在某个地方,例如,Redis 或某种缓存机制再次由您决定,只要确保获取和检索应该很快。
现在,在发送消息时,只需从缓存中提取 socketId
并使用以下代码在该 socketId
上发出消息,
io.to(socket.id).emit(`message-response`,
message: 'hello'
);
我已经在Angular 和AngularJs 上写了一篇关于这个主题的完整博客文章,你也可以参考这些文章。
编辑 1:
第 1 部分 =>
当您的用户完成登录请求时,然后连接到套接字服务器。
假设您使用 React 或 Angular 成功登录后,您会将用户重定向到主页组件(页面)。在 Home 组件(页面)上,通过传递 userId
来连接套接字服务器,就像这样,
const socket = io(SOCKET_SERVER_BASE_URL, query: `userId=$userId` );
附:您可以从 URL 获取用户 ID,也可以使用取决于您的 cookie。
一旦你在服务器上接收到这个socket连接请求,那么你就可以读取userID
查询并且你可以得到与之关联的socketId并像这样将它存储在缓存中,
io.use( async (socket, next) =>
try
await addSocketIdInCache(
userId: socket.request._query['userId'],
socketId: socket.id
);
next();
catch (error)
// Error
console.error(error);
);
第 2 部分 => 现在,假设您在客户端有一个用户列表,并且您想向特定用户发送消息。
socket.emit(`message`,
message: 'hello',
userId: userId
);
在服务器端,使用UserId
从缓存中获取socketId
。从缓存中获取 socketId 后,发送这样的特定消息,
io.to(socketId).emit(`message-response`,
message: 'hello'
);
希望这会有所帮助。
【讨论】:
正如我所说,当用户登录应用程序时,我正在获取 userId。但是 socketId 会在客户端连接到服务器后立即获得。你的答案完全不清楚。可以举例说明一下吗?以上是关于如果使用 Node.js 在 Socket.io 中的应用程序中登录功能,则为特定用户发出事件的主要内容,如果未能解决你的问题,请参考以下文章
Node.js socket.io.js 未找到或 io 未定义
在重新连接、socket.io、node.js 时重用套接字 id
node.js / socket.io,cookies 只在本地工作
简单的游戏循环 Socket.io + Node.js + Express