【问题标题】:Overriding socket.io's emit and on?覆盖socket.io的发射和开启?
【发布时间】:2012-02-08 14:01:59
【问题描述】:

在开发过程中,能够看到哪些数据包到达和发送对我有很大帮助。这在服务器端使用记录器是可能的。但是,在客户端,没有记录器。我发现自己到处乱扔console.log。

是否可以用 console.log(arguments) 覆盖 socket.emit 和 socket.on?如果我可以在我的套接字之前覆盖它,那将非常优雅。

有人建议我改用 Parser。

你的 2cents 是多少?

编辑

我尝试了加藤的建议并写了以下内容:

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

这行得通。但是,socket.on 的情况并不多。我的策略是用 console.log 包装每个回调。如果您了解 python,这有点像将函数装饰器放在 console.log 参数的回调上。

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

任何人都可以指出为什么猴子修补 socket.on 不起作用?

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    要覆盖 socket.on,您实际上需要覆盖 socket.$emit

    以下示例适用于客户端和服务器端(在 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);
      };
    })();
    

    【讨论】:

    • 谢谢,我修改了您的代码以创建默认侦听器函数和捕获所有事件函数:link
    • 我只是替换了socket.on,它起作用了,socket.io 0.9.16
    • 太糟糕了,我们需要改变 socket.io 的工作方式来实现这一点。在我看来,这是一个非常需要的功能。
    • Lino Silva 你可以通过在javascript中引入localStorage.debug = '*'来开启调试。它将打开 socket io 调试并显示所有执行的操作。
    【解决方案2】:

    工作,测试:

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

    【讨论】:

    • 这可行,但请确保不要在函数内部使用:var packet = packet.data;,这样做会使数据包“无效”并且不会调用调用函数。
    【解决方案3】:

    有一个名为socket.io-wildcard的模块允许在客户端和服务器端使用通配符,不再需要覆盖任何东西

    var io         = require('socket.io')();
    var middleware = require('socketio-wildcard')();
    
    io.use(middleware);
    
    io.on('connection', function(socket) {
      socket.on('*', function(){ /* … */ });
    });
    
    io.listen(8000);
    

    【讨论】:

      【解决方案4】:
      <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>
      

      【讨论】:

      • 是的,你需要使用 slice。您还需要使用_origEmit.apply 而不是call
      • 正确;我显然申请/呼叫阅读障碍;我正在考虑将这两个和 php 的 strpos/in_array 放在我显示器旁边的便利贴上:)
      • 已更新 @clarkf 的 cmets
      • _origEmit 不是origEmit :P
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多