24

During development, it helps me greatly to be able to see what packets arrive and gets sent. This is possible on the server side with logger. On the client end, however, there is no logger. I find myself to be littering console.log all over the place.

Is it possible to override socket.emit and socket.on with console.log(arguments)? If I can override this at the before my socket, it would be really elegant.

Somebody advised me to override the Parser instead.

What's your 2cents on this?

EDIT

I tried Kato's suggestion and wrote the following:

var _origEmit = socket.emit;
socket.emit = function() { 
  console.log("SENT", Array.prototype.slice.call(arguments));
  _origEmit.call(socket, arguments);
};

This works. However, Not so much with socket.on. My strategy is to wrap each callback with a console.log. If you know python, it's kind of like putting function decorators on the callbacks that console.log the arguments.

(function(socket) { 
var _origOn = socket.on;
socket.on = function() { 
  var args = Array.prototype.slice.call(arguments)
    , handlerType = args[0]
    , originalCallback = args[1];

  var wrappedCallback = function() { 
    // replace original callback with a function 
    // wrapped around by console.log
    console.log("RECEIVED", Array.prototype.slice.call(arguments));
    originalCallback.call(socket, arguments);
  }

  _origOn.call(socket, [handlerType, wrappedCallback]);
}

Any one can point to why monkey patching socket.on is not working?

xjq233p_1
  • 7,810
  • 11
  • 61
  • 107

4 Answers4

58

To override socket.on you actually need to override socket.$emit.

Following example works both client and server-side (tested on socket.io 0.9.0):

(function() {
  var emit = socket.emit;
  socket.emit = function() {
    console.log('***','emit', Array.prototype.slice.call(arguments));
    emit.apply(socket, arguments);
  };
  var $emit = socket.$emit;
  socket.$emit = function() {
    console.log('***','on',Array.prototype.slice.call(arguments));
    $emit.apply(socket, arguments);
  };
})();
nme
  • 1,025
  • 10
  • 8
  • Thanks, I modified your code to create a default listener function and a catch all event function: [link](http://stackoverflow.com/questions/10405070/socket-io-client-respond-to-all-events-with-one-handler/19121009#19121009) – leszek.hanusz Oct 01 '13 at 16:23
  • 1
    I simply replaced `socket.on`, and it worked, socket.io 0.9.16 – Feng May 15 '14 at 09:34
  • 2
    Too bad we need to change the way socket.io works to achieve this. Seems to me it's a much desired functionality. – Lino Silva Jun 20 '14 at 09:43
  • Lino Silva you can turn on debug by introducing localStorage.debug = '*' into javascript. It will turn on socket io debug and show all performed operations. – Ajay Mar 17 '16 at 09:01
5

Works, tested:

var _emit = socket.emit;
    _onevent = socket.onevent;

    socket.emit = function () { //Override outgoing
        //Do your logic here
        console.log('***', 'emit', arguments);
        _emit.apply(socket, arguments);
    };

    socket.onevent = function (packet) { //Override incoming
        var args = packet.data || [];
        //Do your logic here
        console.log('***', 'onevent', packet);
        _onevent.call(socket, packet);
    };
Alexander Arutinyants
  • 1,619
  • 2
  • 23
  • 49
  • 1
    This works but make sure not to use this: `var packet = packet.data;` inside the function, doing so makes the packet "invalid" and the call function won't be invoked. – Skoempie May 12 '16 at 14:31
4

There is a module called socket.io-wildcard which allows using wildcards on client and server side, no need to overwrite anything anymore

var io         = require('socket.io')();
var middleware = require('socketio-wildcard')();

io.use(middleware);

io.on('connection', function(socket) {
  socket.on('*', function(){ /* … */ });
});

io.listen(8000);
Marian Klühspies
  • 15,824
  • 16
  • 93
  • 136
0
<script src="/socket.io/socket.io.js"></script>
<script>
  (function() {

      var _origEmit = socket.emit;
      socket.emit = function() {
         console.log(arguments);
         _origEmit.apply(null, Array.prototype.slice.call(arguments));
      };


  })();
</script>
Kato
  • 40,352
  • 6
  • 119
  • 149