Отправка сообщения конкретному клиенту с помощью socket.io и пустой очереди сообщений - PullRequest
36 голосов
/ 02 августа 2011

Я схожу с ума от socket.io!Документация настолько плоха, что просто не соответствует действительности.

Я хочу отправить отзыв конкретному клиенту через socket.io

Моя серверная сторона выглядит так:

app.get('/upload', requiresLogin, function(request, response) {
    response.render('upload/index.jade');
    io.sockets.on('connection', function (socket) {
        console.log('SOCKET ID ' + socket.id);
        io.sockets.socket(socket.id).emit('new', 'hello');
    });
});

и клиентская сторона выглядит так:

$(document).ready(function() {
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js');
    socket.on('new', function (data) { 
        console.log(socket.id);
        console.log(data); 
        //$('#state').html(data.status);
    });
});

но клиент просто ничего не делает.Я перепробовал почти все.Может кто-нибудь сказать мне, что я делаю не так, пожалуйста!(

Ответы [ 9 ]

52 голосов
/ 02 августа 2011

для отправки сообщения конкретному клиенту, за исключением каждого, который подключается к серверу в объекте.

var socketio = require('socket.io');
var clients = {};
var io = socketio.listen(app);

io.sockets.on('connection', function (socket) {
  clients[socket.id] = socket;
});

затем вы можете сделать что-то вроде этого:

var socket = clients[sId];
socket.emit('show', {});
18 голосов
/ 05 октября 2012

Существует несколько способов отправки отзыва конкретному клиенту через socket.io:

  • Как указано в pkyeck, сохраните всех клиентов в объекте, чтобы их можно было отправлять на этиопределенные клиенты позже в ваших обработчиках маршрута, например:

    var sessionsConnections = {};
    sio.on('connection', function (socket) {
      // do all the session stuff
      sessionsConnections[socket.handshake.sessionID] = socket;
    });
    
  • или, используйте встроенную поддержку socket.io для комнат - подпишите каждого клиента в комнате при соединении и отправьте через эту комнатув обработчиках маршрута, например:

    sio.on('connection', function (socket) {
      // do all the session stuff
      socket.join(socket.handshake.sessionID);
      // socket.io will leave the room upon disconnect
    });
    
    app.get('/', function (req, res) {
      sio.sockets.in(req.sessionID).send('Man, good to see you back!');
    });
    

Подтверждение:

http://www.danielbaulig.de/socket-ioexpress/#comment-1158

Обратите внимание, что оба эти примера решения предполагают, что socket.io иExpress были настроены на использование одного и того же хранилища сеансов и, следовательно, ссылаются на одни и те же объекты сеанса.См. Ссылки выше и ниже для более подробной информации о достижении этого:

https://github.com/LearnBoost/socket.io/wiki/Authorizing

7 голосов
/ 02 августа 2011

2 вещи

1) Вы действительно должны разместить свой io.sockets.on(..) вне своего app/update маршрута, чтобы предотвратить добавление нескольких прослушивателей для клиентов.

2) io.sockets.socket (id);не должен использоваться, это должно было быть socket.emit('new', 'hello')

5 голосов
/ 15 июня 2014

В socket.io 1.0 это так и будет работать. Это может работать для более низких версий, но я не могу гарантировать это.

socket.to(socket_id_here).emit('new', 'hello');

Это работает, потому что socket.io автоматически добавляет сокет в комнату с идентификатором сокета при подключении.

Кроме того, если вы планируете перейти на версию 1.0, в API будет много изменений, поэтому иногда вам придется изменить какой-то код, чтобы он работал в версии 1.0.

4 голосов
/ 18 июня 2016

Правильный способ сделать это в Socket.io 1.0+:

io.to(users_socket_id).emit('new', 'hello');

Вы также можете подставить имя комнаты для 'users_socket_id' для передачи в конкретную комнату socket.io.

2 голосов
/ 25 июля 2012

Прежде всего, вы не можете использовать socket.id на стороне клиента.

А затем измените строку

var socket = io.connect('http://localhost:80/socket.io/socket.io.js');

до

var socket = io.connect('http://localhost:80/');

0 голосов
/ 03 ноября 2016

я устал от последней версии node и socket.io ниже, я собираюсь опубликовать полный код

  <ul id="messages"></ul>
<form action="">
  <input id="id1"  /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>

  var io = io.connect();
  $('form').submit(function(){
    io.emit('drumevent', $('#id1').val());
    $('#id1').val('');
    return false;
  });
  io.on('drumevent', function(msg){
  console.log(msg);



    $('#messages').append($('<li></li>').text(msg.message+'    quantity = '+msg.quantity));
  });
</script>

код на стороне сервера

  var usernames = {};io.on('connection', function(socket){usernames["username"] = socket.id;
socket.on('drumevent', function(msg){     
var socketId = socket.id;io.to(socketId).emit('drumevent', data);
0 голосов
/ 15 октября 2016

Вы пробовали использовать?

var socket = io.connect('http://localhost:80/');
0 голосов
/ 28 марта 2016

Я считаю, что io.sockets.socket был удален и являлся проблемой в Socket.IO (https://github.com/socketio/socket.io/issues/1618).

. Вы можете использовать io.sockets.connected [socket.id] и сохранить сокет.идентификатор для ссылки с пользователем через имя пользователя:

var usernames = {};
usernames[username] = socket.id;
// Sending the message
io.sockets.connected[usernames[username]].emit(...);

Я не вижу его в документации, поэтому я могу видеть, что на это не было ответа. Кроме того, если у вас нет никаких ссылокчерез имена пользователей вы можете вместо этого попробовать:

users[socket.id] = socket.id;

, чтобы продублировать ключ и значение для легкого доступа.

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

ДРУГОЕ РЕШЕНИЕ: Отправка сообщения конкретному клиенту с помощью socket.io и node.js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...