Alle Clients mit Socket.io aktualisieren?

79

Ist es möglich, alle Clients zu zwingen, mit socket.io zu aktualisieren? Ich habe Folgendes versucht, aber es scheint andere Clients nicht zu aktualisieren, wenn ein neuer Client eine Verbindung herstellt:

Serverseitiges JavaScript:

Ich versuche, eine Nachricht an alle Clients zu senden, die die aktuelle Anzahl der verbundenen Benutzer enthält. Sie sendet die Anzahl der Benutzer korrekt. Der Client selbst scheint jedoch erst zu aktualisieren, wenn die Seite aktualisiert wurde. Ich möchte, dass dies in Echtzeit geschieht.

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

Clientside JavaScript:

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

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

Antworten:

191

Es wird überhaupt kein Update an die anderen Clients gesendet, sondern nur an den Client, der gerade eine Verbindung hergestellt hat (weshalb das Update beim ersten Laden angezeigt wird).

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

Stattdessen möchten Sie an alle Sockets senden

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

Alternativ können Sie die Broadcast-Funktion verwenden, die eine Nachricht an alle außer dem Socket sendet, der sie startet:

socket.broadcast.emit('users_count', clients);
Matt
quelle
1
Vielen Dank, gibt es einen Unterschied zwischen der Verwendung von Broadcast und der Verwendung von io.sockets.emit?
Jack
4
@Jack Laut Dokumentation bedeutet "Rundfunk bedeutet, eine Nachricht an alle anderen zu senden, mit Ausnahme des Sockets, der sie startet.", Wo ich erwarten würde, dass der andere sie an alle sendet.
Matt
1
Es scheint, dass ich den Fehler gemacht habe, diese Antwort als Bearbeitung zu korrigieren. Da die Bearbeitung abgelehnt wurde, geht es noch einmal so weiter: socket.broadcast.emit und io.sockets.emit sind keine Alternativen zueinander in dem Sinne, dass sie einen großen Unterschied haben. Die Broadcast-Variante sendet an alle Sockets mit Ausnahme des Trigger- Sockets , während die io.sockets-Methode tatsächlich an alle Sockets sendet.
Tiago Espinha
Kann das io.sockets.emitaußerhalb des Anwendungsbereichs von verwendet werden io.sockets.on('connection', function (s){...?
vsync
2
@Matt mit der neuesten Socket.IO-API, io.sockets.emit funktioniert nicht, verwenden Sie stattdessen io.emit.
Gianluca Casati
13

Ich habe festgestellt, dass die Verwendung von socket.broadcast.emit () nur an die aktuelle "Verbindung" sendet, io.sockets.emit jedoch an alle Clients. Hier hört der Server "zwei Verbindungen" ab, bei denen es sich genau um zwei Socket- Namespaces handelt

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

Ich habe versucht, io.sockets.emit () in einem Namespace zu verwenden, aber es wurde vom Client im anderen Namespace empfangen. jedoch socket.broadcast.emit () wird nur den aktuellen Socket - Namespace übertragen.

Houkanshan
quelle
3

Ab socket.io Version 0.9 hat "emit" bei mir nicht mehr funktioniert und ich habe "send" verwendet.

Folgendes mache ich:

Serverseite :

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

Kundenseite:

ws = io.connect...
ws.on('message', function(data)
{
var sampleAttributes = fullData.split(',');
if (sampleAttributes[0]=="NumberOfClients")
        {
            console.log("number of connected clients = "+sampleAttributes[1]);
        }
});
Katie
quelle
1
Dann müssen Sie etwas falsch machen ... Der aktuelle Dokumentstatus " emit
Adam
0

Sie können diesem Beispiel folgen, um Ihr Szenario zu implementieren.

Sie können allen Clients erlauben, sich einem Gemeinschaftsraum anzuschließen, um einige Updates zu senden. Jede Steckdose kann sich wie folgt dem Raum anschließen:

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

Dann können Sie Clients Schlüssel in Ihre Sockets eingeben lassen, die die Daten mehrerer Clients (ID und Status) enthalten. Wenn sich der Status eines Clients ändert, können Sie ein Änderungsereignis auf dem Socket wie folgt erhalten:

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

und jetzt möchten Sie, dass alle anderen Clients aktualisiert werden, damit Sie Folgendes tun können:

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

Dadurch wird das Ereignis STATUS_CHANGE an alle Sockets ausgegeben, die dem Raum "Clientpräsenz" beigetreten sind. Anschließend können Sie dasselbe Ereignis auf der Clientseite abfangen und den Status eines anderen Clients aktualisieren.

Rdavial
quelle