it-swarm.com.de

Senden Sie eine Nachricht an einen bestimmten Client mit socket.io und node.js

Ich arbeite mit socket.io und node.js und bis jetzt scheint es ziemlich gut zu sein, aber ich weiß nicht, wie ich eine Nachricht vom Server an einen bestimmten Client senden soll:

client.send(message, receiverSessionId)

Aber weder die .send() noch die .broadcast() Methoden scheinen mein Bedürfnis zu befriedigen.

Als mögliche Lösung habe ich gefunden, dass die .broadcast() -Methode als zweiten Parameter ein Array von SessionIds akzeptiert, an die die Nachricht nicht gesendet wird, sodass ich ein Array mit allen in diesem Moment verbundenen SessionIds übergeben kann An den Server, außer an den, an den ich die Nachricht senden möchte, aber ich bin der Meinung, dass es eine bessere Lösung geben muss.

Irgendwelche Ideen?

173
Rodolfo Palma

Nun, dafür muss man sich den Kunden schnappen (Überraschung), man kann entweder den einfachen Weg gehen:

var io = io.listen(server);
io.clients[sessionID].send()

Was vielleicht kaputt geht, ich bezweifle es kaum, aber es ist immer eine Möglichkeit, dass io.clients kann sich ändern. Gehen Sie daher vorsichtig vor

Oder Sie behalten die Clients selbst im Auge und fügen sie Ihrem eigenen Objekt clients im Listener connection hinzu und entfernen sie im Listener disconnect.

Ich würde das letztere verwenden, da Sie abhängig von Ihrer Anwendung sowieso mehr Status auf den Clients haben möchten, also so etwas wie clients[id] = {conn: clientConnect, data: {...}} könnte die Arbeit erledigen.

90
Ivo Wetzel

Ivo Wetzels Antwort scheint in Socket.io 0.9 nicht mehr gültig zu sein.

Kurz gesagt, Sie müssen jetzt den socket.id Speichern und io.sockets.socket(savedSocketId).emit(...) verwenden, um Nachrichten an ihn zu senden.

So habe ich das in Clustered Node.js Server funktioniert:

Zuerst müssen Sie Redis store als Speicher festlegen, damit Nachrichten prozessübergreifend gesendet werden können:

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

});

Ich habe den Clustering-Code hier weggelassen, da dies die Übersichtlichkeit erhöht, aber das Hinzufügen ist trivial. Fügen Sie einfach alles zum Worker-Code hinzu. Weitere Dokumente hier http://nodejs.org/api/cluster.html

169
Epeli

jede Steckdose verbindet einen Raum mit einer Steckdosen-ID für einen Namen

io.to(socket#id).emit('hey')

docs: http://socket.io/docs/rooms-and-namespaces/#default-room

Prost

86
Matic Kogovšek

Die einfachste und eleganteste Lösung

Es ist so einfach wie:

client.emit("your message");

Und das ist es.

Aber wie? Gib mir ein Beispiel

Was wir alle brauchen, ist in der Tat ein vollständiges Beispiel, und das ist, was folgt. Dies wurde mit der neuesten socket.io-Version (2.0.3) getestet und es wird auch modernes Javascript verwendet (das wir jetzt alle verwenden sollten).

Das Beispiel besteht aus zwei Teilen: einem Server und einem Client. Immer wenn ein Client eine Verbindung herstellt, erhält er vom Server eine periodische Sequenznummer. Für jeden neuen Client wird eine neue Sequenz gestartet, sodass der Server diese einzeln nachverfolgen muss. Hier kommt das "Ich muss eine Nachricht an einen bestimmten Client senden" ins Spiel. Der Code ist sehr einfach zu verstehen. Mal sehen.

Server

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

Der Server beginnt, Port 8000 auf eingehende Verbindungen zu überwachen. Wenn einer eintrifft, fügt er diesen neuen Client zu einer Karte hinzu, damit er seine Sequenznummer verfolgen kann. Es lauscht auch auf das disconnect -Ereignis dieses Clients, wenn es von der Map entfernt wird.

Jede Sekunde wird ein Timer ausgelöst. Wenn dies der Fall ist, durchläuft der Server die Karte und sendet eine Nachricht mit der aktuellen Sequenznummer an jeden Client. Es erhöht es dann und speichert die Nummer wieder in der Karte. Das ist alles was dazu gehört. Kinderleicht.

Klient

Der Client-Teil ist noch einfacher. Es stellt nur eine Verbindung zum Server her und wartet auf das seq-num Meldung, die bei jedem Eintreffen auf der Konsole ausgegeben wird.

client.js

const
    io = require("socket.io-client"),
    ioClient = io.connect("http://localhost:8000");

ioClient.on("seq-num", (msg) => console.info(msg));

Beispiel ausführen

Installieren Sie die erforderlichen Bibliotheken:

npm install socket.io
npm install socket.io-client

Führen Sie den Server aus:

node server

Öffnen Sie andere Terminalfenster und rufen Sie so viele Clients auf, wie Sie möchten:

node client

Ich habe auch ein Gist mit dem vollständigen Code vorbereitet hier .

74
Lucio Paiva

In 1.0 sollten Sie verwenden:

io.sockets.connected[socketid].emit();
33
PHPthinking

Sie können verwenden

// Nachricht nur an Absender-Client senden

socket.emit('message', 'check this');

// oder Sie können an alle Listener einschließlich des Absenders senden

io.emit('message', 'check this');

// An alle Listener außer dem Absender senden

socket.broadcast.emit('message', 'this is a message');

// oder du kannst es in einen Raum schicken

socket.broadcast.to('chatroom').emit('message', 'this is the message to all');

29
DecoderNT

Welche Version wir auch verwenden, wenn wir nur console.log () das "io" -Objekt verwenden, das wir in unserem serverseitigen NodeJS-Code verwenden, [z. io.on ('connection', function (socket) {...});], wir können sehen, dass "io" nur ein json-Objekt ist und es viele untergeordnete Objekte gibt, in denen die Socket-ID und Socket-Objekte gespeichert sind.

Ich benutze socket.io Version 1.3.5, übrigens.

Wenn wir uns das io-Objekt ansehen, enthält es:

 sockets:
  { name: '/',
    server: [Circular],
    sockets: [ [Object], [Object] ],
    connected:
     { B5AC9w0sYmOGWe4fAAAA: [Object],
       'hWzf97fmU-TIwwzWAAAB': [Object] },

hier können wir die Socketids "B5AC9w0sYmOGWe4fAAAA" usw. sehen.

io.sockets.connected[socketid].emit();

Wiederum können wir bei weiterer Betrachtung Segmente sehen wie:

 eio:
  { clients:
     { B5AC9w0sYmOGWe4fAAAA: [Object],
       'hWzf97fmU-TIwwzWAAAB': [Object] },

Also können wir von hier aus einen Socket abrufen

io.eio.clients[socketid].emit();

Auch unter Motor haben wir,

engine:
 { clients:
    { B5AC9w0sYmOGWe4fAAAA: [Object],
      'hWzf97fmU-TIwwzWAAAB': [Object] },

So können wir auch schreiben,

io.engine.clients[socketid].emit();

Ich denke, wir können unser Ziel auf eine der drei oben aufgeführten Arten erreichen.

  1. io.sockets.connected [socketid] .emit (); ODER
  2. io.eio.clients [socketid] .emit (); ODER
  3. io.engine.clients [socketid] .emit ();
12
Suman Barick

Du kannst das

Auf dem Server.

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

Und auf dem Client ist es sehr einfach zu handhaben.

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)
    })
11
abhaygarg12493

Stellen Sie ab Version 1.4.5 sicher, dass Sie in io.to () eine ordnungsgemäß vorangestellte socketId angeben. Ich habe die socketId genommen, die der Client zum Debuggen angemeldet hat, und sie war ohne Präfix, sodass ich für immer gesucht habe, bis ich es herausgefunden habe! Möglicherweise müssen Sie dies so tun, wenn der ID, die Sie haben, kein Präfix vorangestellt ist:

io.to('/#' + socketId).emit('myevent', {foo: 'bar'});
6
risuch

io.sockets.sockets [socket.id] .emit (...) hat bei mir in v0.9 funktioniert

4
aljosa

Mit Socket.IO können Sie Ihren Sockets einen Namespace zuweisen, was im Wesentlichen das Zuweisen verschiedener Endpunkte oder Pfade bedeutet.

Dies könnte helfen: http://socket.io/docs/rooms-and-namespaces/

0
Igor T.