如何使用 socket.io 向特定客户端发送消息

IT技术 javascript jquery ajax node.js socket.io
2021-02-06 10:57:14

我从 socket.io + node.js 开始,我知道如何在本地发送消息和广播socket.broadcast.emit()功能:-所有连接的客户端都收到相同的消息。

现在,我想知道如何向特定客户端发送私人消息,我的意思是一个用于 2 人(客户端到客户端流)之间私人聊天的套接字。谢谢。

6个回答

您可以使用 socket.io 房间。从客户端发出一个带有任何唯一标识符(电子邮件、ID)的事件(在这种情况下,“加入”可以是任何东西)。

客户端:

var socket = io.connect('http://localhost');
socket.emit('join', {email: user1@example.com});

现在,从服务器端使用该信息为该用户创建一个独特的房间

服务器端:

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('join', function (data) {
    socket.join(data.email); // We are using room of socket io
  });
});

所以,现在每个用户都加入了一个以用户电子邮件命名的房间。因此,如果您想向特定用户发送消息,您只需要

服务器端:

io.sockets.in('user1@example.com').emit('new_msg', {msg: 'hello'});

在客户端要做的最后一件事是监听“new_msg”事件。

客户端:

socket.on("new_msg", function(data) {
    alert(data.msg);
}

我希望你明白。

请更改这一行 io.socket.in('user1@example.com').emit('new_msg', {msg: 'hello'}); 像这样 io.sockets.in('user1@example.com').emit('new_msg', {msg: 'hello'});
2021-03-15 10:57:14
您如何{email: user1@example.com}为所有连接创建不同的应用程序的所有客户端是否都有用户user1@example.com我如何使其成为user2@example.com连接的第二个客户端的用户,以便我可以拥有不同的房间。对不起,如果这是一个烦人的问题。
2021-03-17 10:57:14
喜欢这个解决方案,但我相信这里的安全性受到了影响。如果我在客户端更改脚本中的电子邮件怎么办。现在我也可以阅读其他私人消息了。你在说什么?
2021-03-21 10:57:14
它不必是电子邮件我提到了任何唯一标识符
2021-04-01 10:57:14
这个答案比目前接受的答案好得多。原因如下:1) 您不必管理和清理全局客户端数组。2) 即使用户在同一页面上打开了多个选项卡,它也能工作。3)它可以很容易地扩展到与节点集群(多个进程)一起使用socket.io-redis
2021-04-09 10:57:14

当用户连接时,它应该使用必须唯一的用户名向服务器发送消息,例如电子邮件。

一对用户名和套接字应该存储在这样的对象中:

var users = {
    'userA@example.com': [socket object],
    'userB@example.com': [socket object],
    'userC@example.com': [socket object]
}

在客户端,使用以下数据向服务器发出一个对象:

{
    to:[the other receiver's username as a string],
    from:[the person who sent the message as string],
    message:[the message to be sent as string]
}

在服务器上,侦听消息。当收到消息时,将数据发送给接收者。

users[data.to].emit('receivedMessage', data)

在客户端,侦听来自名为“receivedMessage”的服务器的发射,通过读取数据,您可以处理它来自谁以及发送的消息。

您将如何将套接字对象存储在数据存储中?如果您有多个节点进程,我假设这不起作用。
2021-03-14 10:57:14
我建议不要使用这个解决方案。我最终浪费了很多时间试图克服这种方法的局限性。请参阅@az7ar 的解决方案和此解释,了解为什么它更好
2021-03-27 10:57:14
@丹尼尔奎+1。更好地使用本机功能。谢谢!
2021-03-27 10:57:14
如果您使用此解决方案,那么您必须了解: 1. 当用户断开连接时,您必须清理“用户”对象 2. 它不支持第二个连接 - 例如来自另一个浏览器。因此,如果用户从另一个浏览器连接 - 旧连接将被覆盖。
2021-04-04 10:57:14
@chovy 你必须使用 redis。检查这个github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
2021-04-12 10:57:14

当然: 简单地说,

这是你需要的:

io.to(socket.id).emit("event", data);

每当用户加入服务器时,都会生成套接字详细信息,包括 ID。这个 ID 真的有助于向特定的人发送消息。

首先我们需要将所有的 socket.ids 存储在数组中,

var people={};

people[name] =  socket.id;

这里的名字是接收者的名字。例子:

people["ccccc"]=2387423cjhgfwerwer23;

所以,现在我们可以在发送消息时获取带有接收者名称的 socket.id:

为此,我们需要知道接收者名称。您需要将接收器名称发送到服务器。

最后的事情是:

 socket.on('chat message', function(data){
io.to(people[data.receiver]).emit('chat message', data.msg);
});

希望这对你有用。

祝你好运!!

您可以创建客户端和服务器端代码。?我是 scoket 编程的新手。hmahajan.dmi@gmail.com
2021-03-15 10:57:14
如果有两个以上的用户,它将无法正常工作
2021-03-16 10:57:14
每次用户连接套接字 id 更改时,如果用户在多个选项卡中打开您的应用程序,它将收到对您存储并发送到其他套接字连接的一个响应
2021-03-24 10:57:14
@HARISH,请参考以下链接,解释了什么是真正的从客户端side..i希望发生这可以帮助你更多.. socket.io/get-started/chat
2021-04-06 10:57:14
但是如果用户同时与 2 个人聊天呢?来自两个用户的消息不会同时出现在两个窗口中吗?
2021-04-13 10:57:14

你可以参考 socket.io房间当您握手套接字时 - 您可以将他加入命名房间,例如“user.#{userid}”。

之后,您可以通过方便的名称向任何客户端发送私人消息,例如:

io.sockets.in('user.125').emit('new_message', {text: "Hello world"})

在上面的操作中,我们向用户“125”发送“new_message”。

谢谢。

首先,您必须了解此用户名在所有用户中必须是唯一的。第二个 - 你没有忘记在客户端订阅发出的消息吗?
2021-03-21 10:57:14
有人能帮我解决这个问题吗,我真的被困住了,我想添加一个链接到我的套接字的用户名,并允许我的应用程序向特定用户发送消息,没有聊天室,它是一个类似 Facebook 的信使。知道的话谢谢!
2021-03-24 10:57:14
@VladimirKurijov,Katcha 先生不想使用 Rooms,我同意这不是他问题的解决方案。
2021-03-27 10:57:14
这样做的问题是你失去了使用回调的能力,因为它们在广播中是不允许的,这就是你在这里真正要做的,广播到他的私人房间。
2021-03-31 10:57:14
嗨,伙计,感谢您的第一个回答,我会尝试并让您知道这一点,因为我不想建立聊天,而是像您可以在 Facebook 网络上使用的私人信使。
2021-04-08 10:57:14

在我们公司的一个项目中,我们使用“房间”方法,它的名称是对话中所有用户的用户 ID 的组合作为唯一标识符(我们的实现更像是 Facebook 信使),例如:

|身份证 | 姓名 |1 | 斯科特 |2 | 苏珊

“房间”名称将是“1-2”(ID 是按升序排列的)并且在断开连接时 socket.io 会自动清理房间

通过这种方式,您只向那个房间发送消息,并且只向在线(连接)用户发送消息(整个服务器发送的包较少)。

我很惊讶没有人看过你的解决方案......我在那之后发布了答案只有我看到了你的答案......
2021-03-22 10:57:14