简体   繁体   中英

socket.io - how to access unhandled messages?

How can you detect that you received a message on a socket.io connection that you do not have a handler for?

example:

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

I didn't find a way to do it like socket.io, but using a simple js function to transform message into json it's doing the same job. Here you can try this:

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

With:

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

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

and

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

I would do so, of course it is the abstract code ... you would have to implement all the listeners and the logic to get the ids of the users to work

Client

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

Server

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

More info: http://socket.io/docs/

By accessing the internals of the socket object you can determine what events it is currently listening for. You can use this server-side code to see if the current message is being handled.

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

Once connected I am handling two events, 'disconnect' and 'chat'. After that I define a handler that catches all messages with socket.conn.on(...).

The message it receives is going to be a string that looks something like this: '2["myEventName","param1","param2"]' . By splitting it along the double quotes we can get the event name.

We then peek into the internals of socket to find all the keys of socket._events, which happen to be the event name strings. If this collection of strings includes our event name, then another handler will take care of it, and we don't have to.

You can test it from the console in the browser. Run socket.emit('some other event') there and you should see your warning come up in the server console.

IMPORTANT NOTE: Normally you should not attempt to externally modify any object member starting with an underscore. Also, expect that any data in it is unstable. The underscore indicates it is for internal use in that object, class or function. Though this object is not stable, it should be up to date enough for us to use it, and we aren't modifying it directly.

Tested with SocketIO version 2.2.0 on Chrome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM