覆盖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.id 不起作用
如何重用 socket.io 发射功能?试图将套接字发射功能附加到 SwiftUI 按钮(操作)?