我正在使用socket.io和node.js,直到现在看起来还不错,但我不知道如何从服务器向特定客户端发送消息,如下所示:
client.send(message, receiverSessionId)
但.send()
和.broadcast()
方法似乎都不能满足我的需求。
我发现作为一种可能的解决方案,是.broadcast()
方法接受一个不发送消息的SessionIds数组作为第二个参数,所以我可以传递一个数组,其中所有的SessionId都连接在那里到服务器的时刻,除了我希望发送消息的那个,但我觉得必须有更好的解决方案。
有什么想法吗?
答案 0 :(得分:169)
Ivo Wetzel的回答似乎在Socket.io 0.9中无效。
简而言之,您现在必须保存socket.id
并使用io.sockets.socket(savedSocketId).emit(...)
向其发送消息。
这就是我在集群Node.js服务器中使用它的方法:
首先,您需要将Redis存储设置为存储,以便消息可以跨进程:
var express = require("express");
var redis = require("redis");
var sio = require("socket.io");
var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);
io.set("store", new sio.RedisStore);
// In this example we have one master client socket
// that receives messages from others.
io.sockets.on('connection', function(socket) {
// Promote this socket as master
socket.on("I'm the master", function() {
// Save the socket id to Redis so that all processes can access it.
client.set("mastersocket", socket.id, function(err) {
if (err) throw err;
console.log("Master socket is now" + socket.id);
});
});
socket.on("message to master", function(msg) {
// Fetch the socket id from Redis
client.get("mastersocket", function(err, socketId) {
if (err) throw err;
io.sockets.socket(socketId).emit(msg);
});
});
});
我在这里省略了聚类代码,因为它使这更加混乱,但添加起来很简单。只需将所有内容添加到工作人员代这里有更多文档http://nodejs.org/api/cluster.html
答案 1 :(得分:91)
你必须抓住客户端(惊喜),你可以采用简单的方法:
var io = io.listen(server);
io.clients[sessionID].send()
可能会破坏,我几乎不怀疑,但io.clients
可能会发生变化,因此请谨慎使用上述内容
或者您自己跟踪客户端,因此您将它们添加到clients
侦听器中您自己的connection
对象中,并将其移除到disconnect
侦听器中。
我会使用后者,因为根据您的应用程序,您可能希望在客户端上拥有更多状态,因此clients[id] = {conn: clientConnect, data: {...}}
之类的内容可能会起作用。
答案 2 :(得分:82)
每个套接字都加入一个带有套接字id的房间作为名称,所以你可以
io.to(socket#id).emit('hey')
docs:http://socket.io/docs/rooms-and-namespaces/#default-room
干杯
答案 3 :(得分:73)
这很简单:
client.emit("your message");
就是这样。
我们所有人都需要的是一个完整的例子,接下来就是这样。这是使用最新的socket.io版本(2.0.3)测试的,它也使用现代Javascript(我们现在应该全部使用它)。
该示例由两部分组成:服务器和客户端。每当客户端连接时,它就开始从服务器接收周期性序列号。为每个新客户端启动一个新序列,因此服务器必须单独跟踪它们。这就是“我需要向特定客户发送消息”的用武之地。代码很容易理解。我们来看看吧。
server.js
const
io = require("socket.io"),
server = io.listen(8000);
let
sequenceNumberByClient = new Map();
// event fired every time a new client connects:
server.on("connection", (socket) => {
console.info(`Client connected [id=${socket.id}]`);
// initialize this client's sequence number
sequenceNumberByClient.set(socket, 1);
// when socket disconnects, remove it from the list:
socket.on("disconnect", () => {
sequenceNumberByClient.delete(socket);
console.info(`Client gone [id=${socket.id}]`);
});
});
// sends each client its current sequence number
setInterval(() => {
for (const [client, sequenceNumber] of sequenceNumberByClient.entries()) {
client.emit("seq-num", sequenceNumber);
sequenceNumberByClient.set(client, sequenceNumber + 1);
}
}, 1000);
服务器开始在端口8000上侦听传入连接。当一个人到达时,它会将新客户端添加到地图中,以便跟踪其序列号。它还会监听该客户端的disconnect
事件,当它将其从地图中删除时。
每一秒钟都会启动一个计时器。如果是这样,服务器将遍历地图并使用其当前序列号向每个客户端发送消息。然后它递增它并将数字存储回地图中。这就是它的全部。容易腻。
客户端部分更简单。它只是连接到服务器并侦听seq-num
消息,每次到达时都将其打印到控制台。
client.js
const
io = require("socket.io-client"),
ioClient = io.connect("http://localhost:8000");
ioClient.on("seq-num", (msg) => console.info(msg));
安装所需的库:
npm install socket.io
npm install socket.io-client
运行服务器:
node server
打开其他终端窗口并通过运行生成任意数量的客户端:
node client
我还准备了完整代码here的要点。
答案 4 :(得分:33)
在1.0中你应该使用:
io.sockets.connected[socketid].emit();
答案 5 :(得分:27)
您可以使用
//仅向sender-client发送邮件
socket.emit('message', 'check this');
//或者您可以发送给所有听众,包括发件人
io.emit('message', 'check this');
//发送给除发件人之外的所有听众
socket.broadcast.emit('message', 'this is a message');
//或者您可以将其发送到房间
socket.broadcast.to('chatroom').emit('message', 'this is the message to all');
答案 6 :(得分:12)
如果我们只使用console.log()我们在服务器端nodejs代码中使用的“io”对象,我们正在使用的是什么版本,[例如io.on('connection',function(socket){...});],我们可以看到“io”只是一个json对象,并且存在许多子对象,其中存储了套接字id和套接字对象。 / p>
我正在使用socket.io版本1.3.5,顺便说一句。
如果我们查看io对象,它包含
sockets:
{ name: '/',
server: [Circular],
sockets: [ [Object], [Object] ],
connected:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
在这里我们可以看到socketids“B5AC9w0sYmOGWe4fAAAA”等等。所以,我们可以做到,
io.sockets.connected[socketid].emit();
同样,在进一步检查时,我们可以看到像
这样的细分市场 eio:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
所以,我们可以通过
从这里检索一个套接字io.eio.clients[socketid].emit();
另外,在我们的引擎下,
engine:
{ clients:
{ B5AC9w0sYmOGWe4fAAAA: [Object],
'hWzf97fmU-TIwwzWAAAB': [Object] },
所以,我们也可以写,
io.engine.clients[socketid].emit();
所以,我想我们可以用上面列出的3种方式中的任何一种来实现我们的目标,
答案 7 :(得分:11)
你可以这样做
在服务器上。
global.io=require("socket.io")(server);
io.on("connection",function(client){
console.log("client is ",client.id);
//This is handle by current connected client
client.emit('messages',{hello:'world'})
//This is handle by every client
io.sockets.emit("data",{data:"This is handle by every client"})
app1.saveSession(client.id)
client.on("disconnect",function(){
app1.deleteSession(client.id)
console.log("client disconnected",client.id);
})
})
//And this is handle by particular client
var socketId=req.query.id
if(io.sockets.connected[socketId]!=null) {
io.sockets.connected[socketId].emit('particular User', {data: "Event response by particular user "});
}
在客户端,它很容易处理。
var socket=io.connect("http://localhost:8080/")
socket.on("messages",function(data){
console.log("message is ",data);
//alert(data)
})
socket.on("data",function(data){
console.log("data is ",data);
//alert(data)
})
socket.on("particular User",function(data){
console.log("data from server ",data);
//alert(data)
})
答案 8 :(得分:6)
从版本1.4.5开始,请确保在io.to()中提供正确的前缀socketId。 我正在接受socketId客户端登录调试,它没有前缀所以我最终搜索永远直到我发现!如果您拥有的ID没有前缀,那么您可能必须这样做:
$('#draggable').on('click',function()
{
cloned_element = $("#draggable").clone();
cloned_element.attr("id","").css("position","absolute");
cloned_element.find("p").html("Dropped!");
cloned_element.appendTo("#droppable");
});
答案 9 :(得分:4)
io.sockets.sockets [socket.id] .emit(...)在v0.9中为我工作
答案 10 :(得分:3)
您还可以保持客户的推荐。但这会使您的内存繁忙。
创建一个空对象并将您的客户设置为该对象。
const myClientList = {};
server.on("connection", (socket) => {
console.info(`Client connected [id=${socket.id}]`);
myClientList[socket.id] = socket;
});
socket.on("disconnect", (socket) => {
delete myClientList[socket.id];
});
然后通过该对象的ID致电您的特定客户
myClientList[specificId].emit("blabla","somedata");
答案 11 :(得分:0)
Socket.IO允许您“命名”套接字,这实质上意味着分配不同的端点或路径。