Question

Je travaille avec socket.io et Node.js et jusqu'à présent, il semble assez bon, mais je ne sais pas comment envoyer un message à partir du serveur à un client spécifique, quelque chose comme ceci:

client.send(message, receiverSessionId)

Mais ni le .send() ni les méthodes de .broadcast() semblent fournir mes besoins.

Ce que j'ai trouvé comme solution possible, est que la méthode .broadcast() accepte un second paramètre un tableau de ID de session à laquelle pas envoyer le message, pour que je puisse passer un tableau avec tous les ID de session connectés à ce moment au serveur , sauf celui que je veux envoyer le message, mais je me sens qu'il doit y avoir une meilleure solution.

Toutes les idées?

Était-ce utile?

La solution

Eh bien, vous devez saisir le client pour que (surprise), vous pouvez suivre la voie simple:

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

Ce qui peut se briser, je doute, mais il est toujours possible que io.clients pourrait se changer, alors utilisez ci-dessus avec précaution

Ou vous garder une trace des clients vous-même, donc vous les ajoutez à votre propre objet clients dans l'écouteur connection et les supprimer dans l'écouteur disconnect.

J'utiliserait ce dernier un, car en fonction de votre application, vous pouvez avoir plus d'Etat sur les clients de toute façon, donc quelque chose comme clients[id] = {conn: clientConnect, data: {...}} peut faire le travail.

Autres conseils

La réponse de Ivo Wetzel ne semble pas être valable dans Socket.io 0,9 plus.

En bref, vous devez maintenant enregistrer le socket.id de io.sockets.socket(savedSocketId).emit(...) et utiliser pour envoyer des messages.

Voici comment je suis arrivé ce travail dans le serveur Node.js cluster:

Tout d'abord vous devez définir magasin Redis comme le magasin afin que les messages peuvent aller croisés processus:

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

});

J'omis ici le code regroupement, car il rend cela plus encombré, mais il est trivial d'ajouter. Il suffit d'ajouter tout au code des travailleurs. Plus de docs ici http://nodejs.org/api/cluster.html

chaque prise se joint à une chambre avec un identifiant de prise pour un nom, de sorte que vous pouvez simplement

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

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

Vive

La plus simple, la solution la plus élégante

Il est aussi simple que:

client.emit("your message");

Et voilà.

Mais comment? Donnez-moi un exemple

Ce que nous avons tous besoin est en fait un exemple complet, et que de ce qui suit. Ceci est testé avec la plus récente version socket.io (2.0.3) et il est également en utilisant Javascript moderne (que nous devrions être tout en utilisant maintenant).

L'exemple est constitué de deux parties: un serveur et un client. Chaque fois qu'un client se connecte, il commence à recevoir du serveur un numéro de séquence périodique. Une nouvelle séquence est lancée pour chaque nouveau client, de sorte que le serveur doit garder une trace d'eux individuellement. C'est là que « Je dois envoyer un message à un client particulier » entre en jeu. Le code est très simple à comprendre. Allons voir.

Serveur

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

Le serveur commence l'écoute sur le port 8000 pour les connexions entrantes. Quand on arrive, il ajoute que le nouveau client à une carte afin qu'il puisse garder la trace de son numéro de séquence. Il écoute aussi pour l'événement disconnect de ce client, quand il va le retirer de la carte.

Chaque seconde, une minuterie est déclenchée. Quand il le fait, le serveur marche à travers la carte et envoie un message à chaque client avec son numéro de séquence en cours. Il incrémente et stocke le dos du numéro de la carte. C'est tout ce qui est à lui. Facile comme bonjour.

Client

La partie client est encore plus simple. Il se connecte simplement au serveur et à l'écoute pour le message seq-num, l'impression à la console à chaque fois qu'il arrive.

client.js

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

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

Exécution de l'exemple

Installer les bibliothèques requises:

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

Exécuter le serveur:

node server

ouvrir d'autres terminaux et spawn autant de clients que vous voulez en cours d'exécution:

node client

J'ai également préparé un point essentiel avec le code complet .

1.0, vous devez utiliser:

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

Vous pouvez utiliser

// message d'envoi uniquement à l'expéditeur client

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

// ou vous pouvez envoyer à tous les auditeurs, y compris l'expéditeur

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

// envoyer à tous les auditeurs, sauf l'expéditeur

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

// ou vous pouvez l'envoyer dans une pièce

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

La version Tout ce que nous utilisons si nous venons console.log () l'objet « io » que nous utilisons dans notre côté serveur NodeJS code, [par exemple io.on ( « connexion », la fonction (socket) {...});], nous pouvons voir que « io » est juste un objet JSON et il y a beaucoup d'objets enfant où les objets id socket et socket sont stockés <. / p>

J'utilise socket.io la version 1.3.5, btw.

Si l'on regarde dans l'objet io, il contient,

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

ici, nous pouvons voir les socketids "B5AC9w0sYmOGWe4fAAAA", etc. Ainsi, nous pouvons le faire,

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

Encore une fois, sur une inspection plus poussée, nous pouvons voir segments comme,

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

Alors, nous pouvons récupérer une prise d'ici en faisant

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

En outre, sous le moteur que nous avons,

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

Alors, on peut aussi écrire,

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

Alors, je pense que nous pouvons atteindre notre objectif dans l'une des 3 façons I énumérés ci-dessus,

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

Vous pouvez le faire

Sur le serveur.

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

Et sur le client, il est très facile à manipuler.

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 (...) travaillé pour moi dans v0.9

de la version 1.4.5, assurez-vous de fournir un socketid dans io.to () correctement préfixé. Je prenais le socketid le client connecté à déboguer et il était sans préfixe donc j'ai fini pour toujours chercher jusqu'à ce que j'ai découvert! Donc, vous pourriez avoir à le faire comme ça si l'ID que vous avez est pas préfixé:

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

Socket.IO vous permet de « espace » vos prises de courant, qui a essentiellement un moyen d'affectation différents points de terminaison ou des chemins.

Cela pourrait aider à: http://socket.io/docs/rooms-and-namespaces/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top