Вопрос

Я работаю с Socket.IO и Node.js и до сих пор это кажется довольно хорошим, но я не знаю, как отправить сообщение с сервера на конкретный клиент, что-то вроде этого:

client.send(message, receiverSessionId)

Но ни то .send() и ни то .broadcast() Методы, кажется, поставляют мои потребности.

То, что я нашел как возможное решение, это то, что .broadcast() Метод принимает в качестве второго параметра массив сеансов, на которые не отправляют сообщение, поэтому я мог бы пройти массив со всеми сеансами, подключенными к этому моменту на сервер, кроме которого я желаю отправить сообщение, но я чувствую, что должен быть лучшее решение.

Любые идеи?

Это было полезно?

Решение

Ну, вы должны схватить клиента для этого (сюрприз), вы можете либо пойти на простой способ:

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

Что может сломаться, я сомневаюсь, но это всегда возможность того, что io.clients может быть изменено, поэтому используйте вышеуказанное с осторожностью

Или вы сами отслеживаете клиентов, поэтому вы добавляете их в свой собственный clients объект в connection слушатель и удалить их в disconnect слушатель.

Я бы использовал последний, поскольку в зависимости от вашего приложения, вы, возможно, захотите иметь больше государства на клиентах в любом случае, так что-то вроде clients[id] = {conn: clientConnect, data: {...}} может сделать работу.

Другие советы

Ответ IVO WetZel, похоже, не действует в Socket.io 0,9.

Короче говоря, вы должны сохранить socket.id и использовать io.sockets.socket(savedSocketId).emit(...) отправлять сообщения ей.

Вот как я получил эту работу в кластере Node.js Server:

Сначала вам нужно установить магазин Redis в качестве магазина, чтобы сообщения могли пройти перекрестные процессы:

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

});

Я опущел код кластеризации здесь, потому что он делает это более загробным, но это тривиально, чтобы добавить. Просто добавьте все к рабочему коду. Больше документов здесь http://nodejs.org/api/Cluster.html.

Каждый сокет соединяет комнату с идентификатором сокета для имени, чтобы вы могли просто

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

Документы: http://socket.io/docs/rooms-and-anmasts/#default-room.

Ваше здоровье

Самый простой, самый элегантный раствор

Это так просто, как:

client.emit("your message");

И это все.

Но как? Дайте мне пример

Что нам всем нужно, на самом деле является полным примером, и это далее следует. Это проверено с самой последней версией Socket.IO (2.0.3), и она также использует современный JavaScript (который мы все должны быть использованы сейчас).

Пример состоит из двух частей: сервера и клиента. Всякий раз, когда клиент подключается, он начинает получать от сервера периодического порядкового номера. Новая последовательность начинается для каждого нового клиента, поэтому сервер должен отслеживать их индивидуально. Вот где «Мне нужно отправить сообщение для конкретного клиента» вступает в игру. Код очень просто понять. Давай увидим это.

Сервер

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

Сервер начинает прослушивание порта 8000 для входящих соединений. Когда поступают, он добавляет этот новый клиент на карту, чтобы он мог отслеживать его порядковый номер. Это также слушает этот клиент disconnect Событие, когда он удалит его с карты.

Каждую секунду уволится таймер. Когда он делает, сервер проходит через карту и отправляет сообщение каждому клиенту с его текущим порядковым номером. Затем он увеличивает его и сохраняет номер обратно на карту. Это все, что это к этому. Очень просто.

Клиент

Часть клиента даже проще. Это просто подключается к серверу и слушает для seq-num Сообщение, печатая его в консоль каждый раз, когда он поступает.

client.js

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

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

Запуск примера

Установите необходимые библиотеки:

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

Запустите сервер:

node server

Откройте другие оконечные окна и нередите столько клиентов, сколько хотите под управлением:

node client

Я также подготовил глотку с полным кодом здесь.

В 1.0 вы должны использовать:

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

Ты можешь использовать

// Отправить сообщение только отправителю-клиенту

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

// или вы можете отправить всем слушателям, включая отправителя

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

// отправить всем слушателям, кроме отправителя

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

// или вы можете отправить его в комнату

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

Какую бы версию мы используем, если мы просто Console.log () объект «IO», который мы используем в нашем коде Nodejs Server Side, [например, IO.ON (подключение », функция (сокет) {...});];] , мы видим, что «IO» - это просто объект JSON, и есть много дочерних объектов, где хранятся много детских объектов и объектов гнезда.

Я использую Socket.IO версии 1.3.5, кстати.

Если мы посмотрим в объекте IO, он содержит,

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

Здесь мы можем увидеть сознание «B5AC9W0Symogwe4faaaa» и т. Д. Итак, мы можем сделать,

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

Опять же, на дальнейшем осмотре мы можем видеть, как такие сегменты,

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

Итак, мы можем получить сокет отсюда, делая

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

Также под двигателем у нас есть,

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

Итак, мы также можем написать,

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

Итак, я думаю, мы можем добиться нашей цели в любом из 3 способов, которые я перечислил выше,

  1. IO.Sockets.Connected [SocketID] .emit (); ИЛИ
  2. io.eio.Clients [SockeId] .emit (); ИЛИ
  3. io.engine.clients [SocketiD] .emit ();

Ты можешь сделать это

На сервере.

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

А на клиенте это очень легко справиться.

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 (...) работал для меня во v0.9

Нашей версии 1.4.5 Убедитесь, что вы предоставляете должным образом префиксельный SockeID в IO.TO (). Я принимал SocketID клиент, который зарегистрирован в отладке, и это было без префикса, поэтому я закончил поиск вечно, пока я не узнал! Таким образом, вам, возможно, придется сделать это, если идентификатор, который у вас будет префиксирован:

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

Socket.io Позволяет вам «пространство пространства имен» ваших розетков, что по существу означает присвоение различных конечных точек или путей.

Это может помочь:http://socket.io/docs/rooms-and-anmages/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top