如果使用 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.onio.emit 方法,我得到了所有用户的响应。但是,我想得到特定用户的响应。

但是我的应用程序包含登录功能,我在 *** 上关注了 this 帖子,他们说 我们需要在一个对象中唯一的 userIdsocketId 以便特定用户发出特定用户的事件。 但是我在登录后得到了 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

使用 Socket.IO + Node.js + ZMQ 发送消息时发生内存泄漏

我是否可以通过socket.io和JavaScript将Unity程序连接到node.js服务器,如果可以,怎么办?