Domanda

Sto lavorando con socket.io e node.js e fino ad ora sembra abbastanza buono, ma non so come inviare un messaggio dal server a un client specifico, qualcosa di simile a questo:

client.send(message, receiverSessionId)

Ma né il .send() né le modalità .broadcast() sembrano fornire il mio bisogno.

Quello che ho trovato come una possibile soluzione, è che il metodo .broadcast() accetta come secondo parametro di una serie di sessioni a cui non inviare il messaggio, in modo da poter passare un array con tutti i SessionIDs collegati in quel momento al server , ad eccezione di quello vorrei inviare il messaggio, ma mi sembra che ci deve essere una soluzione migliore.

Tutte le idee?

È stato utile?

Soluzione

Bene si deve afferrare il client per che (sorpresa), si può andare il modo più semplice:

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

Il che potrebbe rompersi, ne dubito, ma è sempre una possibilità che io.clients potrebbe ottenere cambiato, in modo da utilizzare il sopra con cautela

In alternativa, è tenere traccia dei clienti da soli, quindi li si aggiunge al tuo proprio oggetto clients nell'ascoltatore connection e rimuoverli in chi ascolta disconnect.

I userebbe questi ultimi uno, dal momento che a seconda dell'applicazione in uso si potrebbe desiderare di avere più di stato sui client in ogni caso, in modo da qualcosa come clients[id] = {conn: clientConnect, data: {...}} potrebbe fare il lavoro.

Altri suggerimenti

La risposta di Ivo Wetzel non sembra essere valido in Socket.io 0.9 più.

In breve si deve ora salvare l'socket.id e l'uso io.sockets.socket(savedSocketId).emit(...) per inviare messaggi ad esso.

Questo è come ho ottenuto questo lavoro nel server di Node.js cluster:

Per prima cosa è necessario impostare Redis negozio come il negozio in modo che i messaggi possono andare i processi trasversali:

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

});

I omesso il codice di clustering qui, perché rende questo più ingombra, ma è banale da aggiungere. Basta aggiungere tutto il codice dei lavoratori. Ulteriori documenti qui http://nodejs.org/api/cluster.html

ogni presa si unisce a una stanza con un id presa per un nome, quindi si può solo

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

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

Saluti

Il più semplice, la soluzione più elegante

E 'facile come:

client.emit("your message");

E il gioco è fatto.

Ma come? Fammi un esempio

Quello che tutti abbiamo bisogno è di fatto un esempio completo, ed è quello che segue. Questo è testato con la versione socket.io più recenti (2.0.3) ed è anche utilizzando Javascript moderno (che dovremmo essere il tutto utilizzando ormai).

L'esempio è costituito da due parti: un server e un client. Ogni volta che un client si connette, si inizia a ricevere dal server di un numero di sequenza periodica. Una nuova sequenza viene avviato per ogni nuovo cliente, in modo che il server deve tenere traccia di loro singolarmente. Ecco dove il "Ho bisogno di inviare un messaggio a un particolare client" entra in gioco. Il codice è molto semplice da capire. Vediamolo.

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

Il server si mette in ascolto sulla porta 8000 per le connessioni in entrata. Quando si arriva, si aggiunge che nuovo cliente ad una mappa in modo da poter tenere traccia del suo numero di sequenza. Si ascolta anche per l'evento disconnect che del cliente, quando si sarà rimuoverlo dalla mappa.

Ogni secondo, un timer viene licenziato. Quando lo fa, il server cammina attraverso la mappa e invia un messaggio ad ogni cliente con il suo numero di sequenza corrente. E poi lo incrementa e memorizza il numero di nuovo nella mappa. Questo è tutto ciò che è ad esso. Easy Peasy.

Client

La parte client è ancora più semplice. Si collega semplicemente al server e ascolti per il messaggio seq-num, la stampa alla console ogni volta che arriva.

client.js

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

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

Esecuzione l'esempio

Installare le librerie necessarie:

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

Esegui il server:

node server

aprire altre finestre di terminale e deporre le uova come molti clienti che vuoi eseguendo:

node client

Ho anche preparato un succo con il codice completo qui .

In 1,0 si dovrebbe usare:

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

È possibile utilizzare

// messaggio di invio solo al mittente-client

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

// oppure è possibile inviare a tutti gli ascoltatori tra cui il mittente

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

// inviare a tutti gli ascoltatori, tranne il mittente

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

// oppure è possibile inviare, in una camera

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

Versione Qualunque cosa stiamo usando, se abbiamo appena console.log () dell'oggetto "io" che usiamo nel nostro lato server nodejs codice, [per esempio io.on ( 'connessione', la funzione (presa) {...});], possiamo vedere che "io" è solo un oggetto JSON e ci sono molti oggetti figlio in cui gli oggetti presa id e presa sono memorizzate <. / p>

Sto usando socket.io versione 1.3.5, btw.

Se guardiamo nell'oggetto io, contiene,

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

Qui possiamo vedere le socketids "B5AC9w0sYmOGWe4fAAAA", ecc Quindi, siamo in grado di fare,

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

Ancora una volta, su un'ulteriore ispezione possiamo vedere segmenti come,

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

Quindi, siamo in grado di recuperare una presa da qui facendo

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

Inoltre, sotto il motore che abbiamo,

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

Quindi, possiamo anche scrivere,

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

Quindi, credo che siamo in grado di raggiungere il nostro obiettivo in uno dei 3 modi che ho elencato sopra,

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

Si può fare questo

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

E sul cliente, è molto facile da gestire.

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 (...) ha lavorato per me in v0.9

Dalla versione 1.4.5, assicurarsi di fornire un socketId correttamente prefissato in io.to (). Stavo prendendo il socketId il Cliente registrato per eseguire il debug ed era senza prefisso così ho finito per la ricerca per sempre fino a quando ho scoperto! Così si potrebbe avere a che fare in questo modo se l'ID che hai è non prefisso:

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

Socket.IO consente di “namespace” le vostre prese, che essenzialmente significa assegnare endpoint o percorsi diversi.

Questo potrebbe aiutare: http://socket.io/docs/rooms-and-namespaces/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top