覆盖socket.io的发射和开启?

Posted

技术标签:

【中文标题】覆盖socket.io的发射和开启?【英文标题】:Overriding socket.io's emit and on? 【发布时间】: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 不起作用?

【问题讨论】:

【参考方案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

以上是关于覆盖socket.io的发射和开启?的主要内容,如果未能解决你的问题,请参考以下文章

如何在socket.io中发射到房间? [复制]

socket.io 发射在 socket.on 中不起作用

当存储在变量中时,Socket.io 发射到 socket.id 不起作用

如何重用 socket.io 发射功能?试图将套接字发射功能附加到 SwiftUI 按钮(操作)?

Socket.io 发射是不是可以乱序到达?如果易变怎么办?

如何为 Socket IO 通知实现度量中间件,应该跟踪发射和侦听器事件?