使用Socket.io更新所有客户端?


78

是否可以强制所有客户端使用socket.io更新?我已经尝试了以下方法,但是当新客户端连接时,它似乎并没有更新其他客户端:

服务器端JavaScript:

我正在尝试向所有客户端发送一条消息,其中包含当前已连接的用户数,它可以正确发送用户数量...。但是,客户端本身似乎不会更新,直到刷新页面为止。我希望这是实时的。

var clients = 0;
io.sockets.on('connection', function (socket) {
  ++clients;
  socket.emit('users_count', clients);    
  socket.on('disconnect', function () {
    --clients;
  });
});

客户端JavaScript:

var socket = io.connect('http://localhost');

socket.on('connect', function(){
  socket.on('users_count', function(data){
    $('#client_count').text(data);
    console.log("Connection");
  });
});

Answers:


190

实际上,它根本没有向其他客户端发送更新,而是向刚刚连接的客户端发送(这就是为什么您在初次加载时看到更新的原因)

// socket is the *current* socket of the client that just connected
socket.emit('users_count', clients); 

相反,您想发射到所有套接字

io.sockets.emit('users_count', clients);

另外,您可以使用广播功能,该功能向启动该套接字的套接字以外的所有人发送消息:

socket.broadcast.emit('users_count', clients);

1
谢谢,使用广播和使用io.sockets.emit有什么不同?
杰克

3
@Jack根据文档,“广播意味着将消息发送到其他人,除了启动它的套接字。”,我希望其他人也可以将消息发送给所有人。
马特

1
似乎我犯了一个错误,即对此答案进行更正以作为编辑。由于编辑被拒绝,因此再说一次:socket.broadcast.emit和io.sockets.emit在意义上有很大不同,它们不是彼此替代的。broadcast变量会向触发套接字之外的所有套接字发出,而io.sockets方法确实会向所有套接字发出。
Tiago Espinha 2013年

可以在io.sockets.emit范围之外使用io.sockets.on('connection', function (s){...吗?
vsync

2
@Matt使用最新的Socket.IO API,io.sockets.emit不起作用,请改用io.emit。
Gianluca Casati

13

我发现使用socket.broadcast.emit()仅广播到当前的“连接”,但是io.sockets.emit将广播到所有客户端。在这里,服务器正在侦听“两个连接”,这恰好是2个套接字名称空间

io.of('/namespace').on('connection', function(){
    socket.broadcast.emit("hello");
});
io.of('/other namespace').on('connection',function(){/*...*/});

我尝试在一个名称空间中使用io.sockets.emit(),但是客户端在另一个名称空间中接收了它。但是socket.broadcast.emit()只会广播当前的套接字名称空间。


3

从socket.io 0.9版开始,“ emit”不再对我有用,并且我一直在使用“ send”

这是我在做什么:

服务器端

var num_of_clients = io.sockets.clients().length;
io.sockets.send(num_of_clients);

客户端:

ws = io.connect...
ws.on('message', function(data)
{
var sampleAttributes = fullData.split(',');
if (sampleAttributes[0]=="NumberOfClients")
        {
            console.log("number of connected clients = "+sampleAttributes[1]);
        }
});

1
您必须做错了什么,然后...当前文档状态为“发出” socket.io/docs
Adam

0

您可以按照以下示例实施方案。

您可以让所有客户端加入一个公共会议室以发送一些更新。每个套接字都可以像这样进入房间:

currentSocket.join("client-presence") //can be any name for room

然后,您可以将客户端密钥插入包含多个客户端数据(标识和状态)的套接字中,如果一个客户端的状态发生更改,您可以在套接字上接收更改事件,如下所示:

socket.on('STATUS_CHANGE',emitClientsPresence(io,namespace,currentSocket); //event name should be same on client & server side for catching and emiting

现在您希望所有其他客户端得到更新,因此您可以执行以下操作:

emitClientsPresence => (io,namespace,currentSocket) {
  io.of(namespace)
        .to(client-presence)
        .emit('STATUS_CHANGE', { id: "client 1", status: "changed status" });
}

这将向所有已加入“客户端存在”空间的套接字发出STATUS_CHANGE事件,然后您可以在客户端捕获同一事件并更新其他客户端的状态。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.