84 votes

Mettre à jour tous les clients utilisant Socket.io ?

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

Serverside JavaScript :

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 jusqu'à ce que la page ait été rafraîchie. Je veux que cela se produise 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");
  });
});

204voto

Matt Points 15107

Il n'envoie pas du tout de mise à jour aux autres clients, mais seulement au client qui vient de se connecter (c'est pourquoi vous voyez la mise à jour au 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 prises de courant

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

Sinon, vous pouvez utiliser la fonction de diffusion, qui envoie un message à tout le monde, sauf à la socket qui l'a lancé :

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

1 votes

Merci, y a-t-il une différence entre l'utilisation de broadcast et l'utilisation de io.sockets.emit ?

4 votes

@Jack D'après la documentation, "Diffuser signifie envoyer un message à tout le monde sauf à la socket qui l'a lancé", alors que je m'attendrais à ce que l'autre l'envoie à tout le monde.

1 votes

Il semble que j'ai fait l'erreur de fournir une correction à cette réponse en tant qu'édition. Puisque l'édition a été rejetée, voici à nouveau : socket.broadcast.emit et io.sockets.emit ne sont pas des alternatives l'une à l'autre dans le sens où elles ont une différence majeure. La variante broadcast émet vers toutes les sockets sauf au socket déclencheur, alors que la méthode io.sockets émet réellement vers tous les sockets.

14voto

houkanshan Points 71

J'ai découvert qu'en utilisant socket.broadcast.emit() ne diffusera que vers la "connexion" en cours, mais io.sockets.emit sera diffusé à tous les clients. Ici, le serveur écoute "deux connexions", qui sont exactement deux sockets. espaces de noms

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

j'ai essayé d'utiliser io.sockets.emit() dans un espace de nom mais il a été reçu par le client dans l'autre espace de nom. cependant socket.broadcast.emit() diffusera simplement l'espace de nom de la socket actuelle.

3voto

Kayvar Points 4239

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

Voilà ce que je fais :

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]);
        }
});

1 votes

Vous devez faire quelque chose de mal alors... La documentation actuelle indique "emit" socket.io/docs

1voto

Tô Minh Tiến Points 259

Selon cette Radiodiffusion . Avec le serveur nodejs, vous pouvez utiliser ceci :

io.emit('event_id', {your_property: 'your_property_field'});

Veillez à initialiser websocket, par exemple :

var express = require('express');
var http = require('http');
var app = express();
var server = http.Server(app);
var io = require('socket.io')(server);

app.get('/', function (req, res) {
    res.send('Hello World!');
    io.emit('event_hello', {message: 'Hello Socket'});
});

server.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Dans ce cas, lorsque l'utilisateur atteint votre serveur, un "event_hello" sera diffusé à tous les clients web-socket avec un objet json {message : 'Hello Socket'}.

0voto

Rdavial Points 29

Vous pouvez suivre cet exemple pour mettre en œuvre votre scénario.

Vous pouvez permettre à tous les clients de rejoindre une salle commune pour envoyer des mises à jour. Chaque socket peut rejoindre la salle comme ceci :

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

Ensuite, vous pouvez avoir des clés de clients dans vos sockets qui contiennent les données de plusieurs clients (id et statut) et si le statut d'un client change, vous pouvez recevoir un événement de changement sur le socket comme ceci :

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

et maintenant vous voulez que tous les autres clients soient mis à jour, donc vous pouvez faire quelque chose comme ça :

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

Cela émettra l'événement STATUS_CHANGE à tous les sockets qui ont rejoint la salle "client-presence" et vous pourrez ensuite attraper le même événement du côté client et mettre à jour le statut des autres clients.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X