Frage

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

client.send(message, receiverSessionId)

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

Was ich als eine mögliche Lösung gefunden habe, ist, dass die .broadcast() Methode akzeptiert als zweiten Parameter ein Array von SessionIds, an denen die Nachricht nicht senden, so dass ich ein Array mit allen SessionIds in diesem Moment mit dem Server verbunden passieren könnte , mit Ausnahme des einen möchte ich die Nachricht senden, aber ich fühle es muss eine bessere Lösung sein.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Nun müssen Sie den Client greifen für diese (Überraschung), können Sie entweder den einfachen Weg gehen:

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

Welche brechen kann, wage ich zu bezweifeln, aber es ist immer eine Möglichkeit, dass io.clients vielleicht umziehen, so dass die mit Vorsicht oben verwenden

Oder Sie behalten den Überblick über die Kunden selbst, daher können Sie sie zu Ihrem eigenen clients Objekt im connection Zuhörer hinzufügen und sie im disconnect Zuhörer entfernen.

würde ich das letztere verwenden, da je nach Anwendung, die Sie mehr Staat auf den Clients trotzdem haben möchten, so etwas wie clients[id] = {conn: clientConnect, data: {...}} die Arbeit machen könnten.

Andere Tipps

Ivo Wetzel Antwort scheint nicht mehr in Socket.io 0.9 gültig.

Kurz gesagt müssen Sie jetzt speichern die socket.id und Verwendung io.sockets.socket(savedSocketId).emit(...) Nachrichten an sie senden.

Das ist, wie ich diese Arbeit in geclusterten Node.js Server:

Zuerst müssen Sie Redis Speicher als Speicher setzen, so dass Nachrichten Quer Prozesse gehen 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 weggelassen, um den Clustering-Code hier, weil es diese mehr unübersichtlich macht, aber es ist trivial hinzuzufügen. Einfach alles des Arbeiter-Code hinzufügen. Weitere Dokumente hier http://nodejs.org/api/cluster.html

jede Steckdose verbindet ein Zimmer mit einer Socket-ID für einen Namen, so können Sie einfach

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

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

Prost

Die einfachste, eleganteste Lösung

Es ist so einfach wie:

client.emit("your message");

Und das ist es.

Aber wie? Geben Sie mir ein Beispiel

Was wir alle brauchen ist in der Tat ein vollständiges Beispiel, und das ist, was folgt. Dies wird mit der neuesten Version socket.io (2.0.3) getestet und es ist auch mit modernen Javascript (die wir alle mit mittlerweile sein sollen).

Das Beispiel besteht aus zwei Teilen: einem Server und einem Client. Jedes Mal, wenn ein Client eine Verbindung, beginnt sie vom Server empfängt eine periodische Sequenznummer. Eine neue Sequenz wird für jeden neuen Client gestartet, so dass der Server Spur von ihnen einzeln zu halten hat. Das ist, wo die „Ich brauche eine Nachricht an einen bestimmten Client senden“ ins Spiel kommt. Der Code ist sehr einfach zu verstehen. Mal sehen es.

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 startet auf Port 8000 auf eingehende Verbindungen zu hören. Wenn man ankommt, fügt es, dass neue Kunden zu einer Karte, so dass es den Überblick über seine Sequenznummer behalten kann. Es ist auch hört für diesen disconnect Ereignis des Kunden, wenn sie es von der Karte entfernen werden.

Jede Sekunde wird ein Timer gebrannt. Wenn es der Fall ist, geht der Server über die Karte und sendet eine Nachricht an jeden Kunden mit seinen aktuellen Sequenznummer. Es erhöht dann sie und speichert die Nummer zurück in der Karte. Das ist alles, was es ist. Kinderleicht.

Client

Der Client-Teil ist sogar noch einfacher. Er verbindet nur mit dem Server und Streams für die seq-num Nachricht, Druck an die Konsole jedes Mal, es ankommt.

client.js

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

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

Ausführen des Beispiel

Installieren Sie die benötigten Bibliotheken:

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

Führen Sie den Server:

node server

Öffnen andere Terminal-Fenster und Laich so viele Kunden, wie Sie wollen, indem Sie:

node client

Ich habe auch bereit, einen Kern mit dem vollständigen Code hier .

1.0 sollten Sie verwenden:

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

Sie können mit

// Nachrichtens nur an den Absender-Client

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

// oder Sie können mit dem Sender an alle Zuhörer senden

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

// send an alle Zuhörer außer dem Absender

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

// oder Sie können es zu einem Raum senden

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

Wie auch immer Version, die wir verwenden, wenn wir nur console.log () das „io“ Objekt, das wir in unserer Server-Seite verwenden NodeJS Code, [z io.on ( ‚Verbindung‘, function (Buchse) {...});], können wir sehen, dass „io“ ist nur ein JSON-Objekt und gibt es viele untergeordnete Objekte, wo die Socket-ID und Socket-Objekte gespeichert werden <. / p>

Ich bin mit Socket.io Version 1.3.5, btw.

Wenn wir in dem io-Objekt aussehen, es enthält,

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

Hier können wir die socketids "B5AC9w0sYmOGWe4fAAAA" usw. So sehen wir tun können,

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

Auch auf weitere Inspektion können wir sehen, Segmente mögen,

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

Wir können also einen Sockel von hier abrufen, indem Sie

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

Also, ich denke wir unser Ziel in einem der drei Wege erreichen kann ich oben aufgeführt,

  1. io.sockets.connected [SocketId] .emit (); ODER
  2. io.eio.clients [SocketId] .emit (); ODER
  3. io.engine.clients [SocketId] .emit ();

Sie können dies tun,

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

io.sockets.sockets [socket.id] .emit (...) für mich gearbeitet in v0.9

Ab Version 1.4.5, müssen Sie bieten Ihnen eine richtig voran SocketId in io.to (). Ich war die SocketId nimmt der Kunde zu debuggen angemeldet und es war ohne Präfix so dass ich die Suche endete für immer, bis ich herausgefunden habe! So können Sie es wie könnte dies tun, wenn die Id Sie wird nicht vorangestellt:

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

Socket.IO ermöglicht es Ihnen, „Namensraum“ Ihre Steckdosen, die im Wesentlichen mittels Zuweisung verschiedene Endpunkte oder Pfade.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top