Pregunta

Estoy trabajando con socket.io y Node.js y hasta ahora parece bastante bueno, pero no sé cómo enviar un mensaje desde el servidor a un cliente específico, algo como esto:

client.send(message, receiverSessionId)

Pero ni el .send() ni los métodos .broadcast() parecen suministrar mi necesidad.

Lo que he encontrado como una posible solución, es que el método .broadcast() acepta como un segundo parámetro de una matriz de SessionIDs a la que no envía el mensaje, por lo que podía pasar una matriz con todos los SessionIDs conectados en ese momento al servidor , excepto el deseo enviar el mensaje, pero siento que debe haber una solución mejor.

¿Alguna idea?

¿Fue útil?

Solución

Bueno, usted tiene que agarrar el cliente para que (sorpresa), puede ir por el camino simple:

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

¿Qué se puede romper, lo dudo, pero es siempre una posibilidad de que io.clients mismo puede cambiar, a fin de utilizar lo anterior con precaución

O hacer un seguimiento de los clientes usted mismo, por lo tanto, se agregan a su propio objeto clients en el oyente connection y eliminarlos en el oyente disconnect.

Yo usaría la última, ya que dependiendo de su aplicación es posible que desee tener más Estado en los clientes de todos modos, así que algo como clients[id] = {conn: clientConnect, data: {...}} podría hacer el trabajo.

Otros consejos

La respuesta de Ivo Wetzel no parece ser válido en Socket.io 0,9 más.

En resumen se debe guardar ahora la socket.id y el uso io.sockets.socket(savedSocketId).emit(...) para enviar mensajes a la misma.

Esto es cómo llegué a este trabajo en el servidor de clúster Node.js:

En primer lugar es necesario configurar tienda Redis como la tienda para que los mensajes pueden ir procesos transversales:

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

});

Me omite el código de la agrupación aquí, ya que hace esto más desordenado, pero es trivial para agregar. Sólo tiene que añadir todo lo que el código de los trabajadores. Más documentos aquí http://nodejs.org/api/cluster.html

cada toma se une a una habitación con un identificador de socket para un nombre, lo que sólo puede

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

docs: http://socket.io/docs/rooms-and -namespaces / # default-habitación

Saludos

La solución más simple más elegante

Es tan fácil como:

client.emit("your message");

Y eso es todo.

Pero, ¿cómo? Dame un ejemplo

Lo que todos necesitamos es, de hecho, un ejemplo completo, y eso es lo que sigue. Esto se prueba con la versión más reciente socket.io (2.0.3) y también está usando Javascript moderna (que deberíamos estar usando todo por ahora).

El ejemplo se compone de dos partes: un servidor y un cliente. Cada vez que un cliente se conecta, comienza a recibir desde el servidor un número de secuencia periódica. Una nueva secuencia se inicia para cada nuevo cliente, por lo que el servidor tiene que realizar un seguimiento de ellos individualmente. Ahí es donde el "Tengo que enviar un mensaje a un cliente en particular" entra en juego. El código es muy sencillo de entender. Vamos a verlo.

Servidor

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

El servidor empieza a escuchar en el puerto 8000 para conexiones entrantes. Cuando uno llega, se añade que el nuevo cliente a un mapa para que pueda llevar un registro de su número de secuencia. También procese el evento disconnect de ese cliente, cuando va a quitarlo del mapa.

Todos y cada segundo, un temporizador se dispara. Cuando lo hace, el servidor de guía a través del mapa y envía un mensaje a cada cliente con su número de secuencia actual. A continuación, incrementa y almacena el número de devolución en el mapa. Eso es todo lo que está a la misma. Peasy fácil.

Cliente

La parte cliente es aún más simple. Simplemente se conecta al servidor y escuchas el mensaje seq-num, la impresión de que a la consola cada vez que llega.

client.js

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

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

Ejecutar el ejemplo

Instalar las bibliotecas necesarias:

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

Ejecutar el servidor:

node server

abrir otras ventanas de terminal y desove tantos clientes como desee ejecutando:

node client

Me han preparado también una esencia con el código completo aquí .

1.0 se debe utilizar:

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

Puede utilizar

// enviar mensaje solamente al remitente-cliente

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

// o puede enviar a todos los oyentes incluyendo el remitente

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

// enviar a todos los oyentes excepto el remitente

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

// o puede enviarlo a un cuarto

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

Cualquiera que sea la versión que está utilizando si sólo console.log () del objeto "io" que utilizamos en nuestro lado del servidor nodejs código, [por ejemplo, io.on ( 'conexión', la función (socket) {...});], podemos ver que "io" es simplemente un objeto JSON y hay muchos objetos infantil donde se almacenan los objetos id socket y socket <. / p>

Estoy utilizando la versión 1.3.5 socket.io, por cierto.

Si nos fijamos en el objeto io, que contiene,

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

Aquí podemos ver las socketids "B5AC9w0sYmOGWe4fAAAA", etc. Por lo tanto, podemos hacerlo,

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

Una vez más, en una posterior inspección podemos ver segmentos como,

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

Por lo tanto, podemos recuperar una toma de aquí haciendo

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

Además, debajo del motor que tenemos,

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

Por lo tanto, también podemos escribir,

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

Por lo tanto, creo que podemos lograr nuestro objetivo en cualquiera de las 3 formas que se enumeran más arriba,

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

Puede hacer esto

En el servidor.

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

Y en el cliente, es muy fácil de manejar.

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 (...) trabajado para mí en v0.9

A partir de la versión 1.4.5, asegúrese de que usted proporciona un socketId correctamente prefijado en io.to (). Yo estaba tomando el socketId el cliente conectado a depurar y que era sin prefijo, así que acabé buscando siempre hasta que descubrí! Así que puede que tenga que hacerlo de esta manera, si el ID que tienen no es el prefijo:

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

Socket.IO le permite “espacio de nombres” sus tomas de corriente, lo cual significa básicamente la asignación de diferentes puntos finales o caminos.

Esta ayuda puede: http://socket.io/docs/rooms-and-namespaces/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top