socket.io - как получить доступ к необработанным сообщениям?

Как определить, что вы получили сообщение по соединению socket.io, для которого у вас нет обработчика?

пример:

// client
socket.emit('test', 'message');

// server
io.on('connection', function (socket) {
  console.log('connection received...');

  // logs all messages
  socket.conn.on('message', function(data) {
    console.log('this gets every message.');
    console.log('how do I get just the ones without explicit handlers?');
  });

  socket.on('other' function(data) {
    console.log('expected message');
  });
}

2 ответа

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

io.on('connection', (socket) => {
    console.log('A user connected.');
    socket.on('disconnect', () => {
        console.log('A user disconnected.');
    });
    socket.on('chat', (msg) => {
        console.log('message: ' + msg);
        io.emit('chat', msg);
    });
    socket.conn.on('message', (msg) => {
        if(!Object.keys(socket._events).includes(msg.split('"')[1])) {
            console.log(`WARNING: Unhandled Event: ${msg}`);
        }
    });
}

После подключения я обрабатываю два события: "отключение" и "чат". После этого я определяю обработчик, который перехватывает все сообщения с помощью socket.conn.on (...).

Полученное сообщение будет строкой, которая выглядит примерно так: '2["myEventName","param1","param2"]', Разбивая его по двойным кавычкам, мы можем получить имя события.

Затем мы заглядываем внутрь сокета, чтобы найти все ключи socket._events, которые являются строками имен событий. Если в эту коллекцию строк входит наше имя события, об этом позаботится другой обработчик, а нам это не нужно.

Вы можете проверить это с консоли в браузере. Бежать socket.emit('some other event') там и вы должны увидеть ваше предупреждение в консоли сервера.

ВАЖНОЕ ПРИМЕЧАНИЕ: как правило, вы не должны пытаться внешне изменить какой-либо элемент объекта, начиная с подчеркивания. Также ожидайте, что любые данные в нем нестабильны. Подчеркивание указывает на то, что оно предназначено для внутреннего использования в этом объекте, классе или функции. Хотя этот объект нестабилен, он должен быть достаточно современным, чтобы мы могли его использовать, и мы не модифицируем его напрямую.

Протестировано с SocketIO версии 2.2.0 на Chrome.

Я не нашел способа сделать это как socket.io, но используя простую функцию js для преобразования сообщения в json, он выполняет ту же работу. Здесь вы можете попробовать это:

function formatMessage(packetType, data) {
    var message = {'packetType': packetType, 'data': data}
    return JSON.stringify(message)
}

С:

socket.on('message', function(packet){
   packet = JSON.parse(packet)

   switch (packet.packetType) {
      case 'init':
   ...

а также

socket.send(formatMessage('init', {message}));

Я бы сделал так, конечно, это абстрактный код... вам бы пришлось реализовать все слушатели и логику, чтобы заставить работать идентификаторы пользователей

клиент

 var currentUser = {
     id: ? // The id of current user
 };
 var socketMessage = {
     idFrom: currentUser.id,
     idTo: ?, // Some user id value
     message: 'Hello there'
 };

 socket.emit('message', socketMessage);

 socket.on('emitedMessage' + currentUser.id, function(message) {
       // TODO: handle message
 });

сервер

 io.on('connection', function (socket) {
     // Handle emit messages
     socket.on('message', function(socketMessage) {
          //  With this line you send the message to a specific user
          socket.emit('emitedMessage-' + socketMessage.idTo, {
                from: socketMessage.idFrom,
                message: socketMessage.message
          });
     });
 });

Больше информации: http://socket.io/docs/

Другие вопросы по тегам