web-dev-qa-db-fra.com

Mettre à jour tous les clients utilisant Socket.io?

Est-il possible de forcer tous les clients à mettre à jour en utilisant socket.io? J'ai essayé ce qui suit, mais il ne semble pas mettre à jour les autres clients lorsqu'un nouveau client se connecte:

JavaScript côté serveur:

J'essaie d'envoyer un message à tous les clients, qui contient le nombre actuel d'utilisateurs connectés, il envoie correctement le nombre d'utilisateurs ... Cependant, le client lui-même ne semble pas se mettre à jour tant que la page n'a pas été actualisée. Je veux que cela se produise est en temps réel.

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

JavaScript côté client:

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

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

En réalité, il ne s'agit pas du tout d'envoyer une mise à jour aux autres clients, mais simplement d'émettre au client qui vient de se connecter (c'est pourquoi vous voyez la mise à jour lors du premier chargement).

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

Au lieu de cela, vous voulez émettre vers tous sockets

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

Alternativement, vous pouvez utiliser la fonction broadcast, qui envoie un message à tout le monde sauf au socket qui le démarre:

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

J'ai constaté que l'utilisation desocket.broadcast.emit ()ne diffusera que vers la "connexion" actuelle, maisio.sockets.emitsera diffusée à tous les clients. ici le serveur écoute "deux connexions", qui sont exactement 2 socket namespaces

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

j'ai essayé d'utiliserio.sockets.emit ()dans un espace de noms, mais il a été reçu par le client dans l'autre espace de noms. Cependant,socket.broadcast.emit ()ne fera que diffuser l'espace de noms actuel du socket. 

13
houkanshan

Depuis la version 0.9 de socket.io, "emit" ne fonctionnait plus pour moi et j'utilise

Voici ce que je fais:

Du côté serveur :

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

Côté client:

ws = io.connect...
ws.on('message', function(data)
{
var sampleAttributes = fullData.split(',');
if (sampleAttributes[0]=="NumberOfClients")
        {
            console.log("number of connected clients = "+sampleAttributes[1]);
        }
});
3
Katie S
You can follow this example for implementing your scenario.

You can let all of clients to join a common room for sending some updates.
Every socket can join room like this: 

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

Then you can have clients key in you sockets which contains multiple client's data(id and status) and if one client's status changes you can receive change event on socket like this:

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

and now you want all other clients to get updated, so you can do something like this:

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

This will emit STATUS_CHANGE event to all sockets that have joined "client-presence" room and then you can catch same event on client side and update other client's status.
0
Rdavial