Socket.io客户端:使用一个处理程序响应所有事件?

Der*_*ley 77 javascript events socket.io

是否可以让socket.io客户端响应所有事件而不必单独指定每个事件?

例如,像这样的东西(显然现在不起作用):

var socket = io.connect("http://myserver");

socket.on("*", function(){
  // listen to any and all events that are emitted from the
  // socket.io back-end server, and handle them here.

  // is this possible? how can i do this?
});
Run Code Online (Sandbox Code Playgroud)

我希望在客户端socket.io代码接收到任何/所有事件时调用此回调函数.

这可能吗?怎么样?

Fli*_*ion 75

更新了socket.io-client 1.3.7的解决方案

var onevent = socket.onevent;
socket.onevent = function (packet) {
    var args = packet.data || [];
    onevent.call (this, packet);    // original call
    packet.data = ["*"].concat(args);
    onevent.call(this, packet);      // additional call to catch-all
};
Run Code Online (Sandbox Code Playgroud)

使用这样:

socket.on("*",function(event,data) {
    console.log(event);
    console.log(data);
});
Run Code Online (Sandbox Code Playgroud)

虽然Mathias Hopf和Maros Pixel的一个很接近,但这些答案对我来说都没有用,这是我调整后的版本.

注意:这只捕获自定义事件,而不是连接/断开连接等

  • 谢谢,这帮我调试了丢失的事件! (2认同)

luk*_*fer 23

看起来socket.io库将它们存储在字典中.因此,如果不修改源代码,请不要认为这是可能的.

来源:

EventEmitter.prototype.on = function (name, fn) {
    if (!this.$events) {
      this.$events = {};
    }

    if (!this.$events[name]) {
      this.$events[name] = fn;
    } else if (io.util.isArray(this.$events[name])) {
      this.$events[name].push(fn);
    } else {
      this.$events[name] = [this.$events[name], fn];
    }

    return this;
  };
Run Code Online (Sandbox Code Playgroud)

  • 也发现了这个:http://stackoverflow.com/questions/8832414/overriding-socket-ios-emit-and-on/8838225 (3认同)

Mar*_*ies 18

最后,有一个名为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);
Run Code Online (Sandbox Code Playgroud)


Kau*_*are 11

干得好 ...

var socket = io.connect();
var globalEvent = "*";
socket.$emit = function (name) {
    if(!this.$events) return false;
    for(var i=0;i<2;++i){
        if(i==0 && name==globalEvent) continue;
        var args = Array.prototype.slice.call(arguments, 1-i);
        var handler = this.$events[i==0?name:globalEvent];
        if(!handler) handler = [];
        if ('function' == typeof handler) handler.apply(this, args);
        else if (io.util.isArray(handler)) {
            var listeners = handler.slice();
            for (var i=0, l=listeners.length; i<l; i++)
                listeners[i].apply(this, args);
        } else return false;
    }
    return true;
};
socket.on(globalEvent,function(event){
    var args = Array.prototype.slice.call(arguments, 1);
    console.log("Global Event = "+event+"; Arguments = "+JSON.stringify(args));
});
Run Code Online (Sandbox Code Playgroud)

这将赶上样事件connecting,connect,disconnect,reconnecting太,所以千万要小心.

  • 这最终是在发布中吗? (3认同)

les*_*usz 9

注意:此答案仅对socket.io 0.x有效

你可以覆盖socket.$ emit

使用以下代码,您有两个新功能:

  • 陷阱所有事件
  • 仅捕获未被旧方法捕获的事件(它是默认侦听器)
var original_$emit = socket.$emit;
socket.$emit = function() {
    var args = Array.prototype.slice.call(arguments);
    original_$emit.apply(socket, ['*'].concat(args));
    if(!original_$emit.apply(socket, arguments)) {
        original_$emit.apply(socket, ['default'].concat(args));
    }
}

socket.on('default',function(event, data) {
    console.log('Event not trapped: ' + event + ' - data:' + JSON.stringify(data));
});

socket.on('*',function(event, data) {
    console.log('Event received: ' + event + ' - data:' + JSON.stringify(data));
});
Run Code Online (Sandbox Code Playgroud)


Dan*_*scu 7

目前(2013年4月)关于暴露事件的GitHub文档提到了一个socket.on('anything').似乎"任何事物"是自定义事件名称的占位符,而不是捕获任何事件的实际关键字.

我刚刚开始使用Web套接字和Node.JS,并立即需要处理任何事件,以及发现发送了什么事件.无法完全相信socket.io中缺少此功能.


Car*_*ira 7

正如v3.0 文档中的那样

socket.onAny((event, ...args) => {
  console.log(`got ${event}`);
});
Run Code Online (Sandbox Code Playgroud)


Fab*_*ani 5

socket.io-client 1.7.3

截至2017年5月,无法使其他任何解决方案完全按照我的方式工作 - 制作拦截器,仅在Node.js上进行测试:

var socket1 = require('socket.io-client')(socketUrl)
socket1.on('connect', function () {
  console.log('socket1 did connect!')
  var oldOnevent = socket1.onevent
  socket1.onevent = function (packet) {
    if (packet.data) {
      console.log('>>>', {name: packet.data[0], payload: packet.data[1]})
    }
    oldOnevent.apply(socket1, arguments)
  }
})
Run Code Online (Sandbox Code Playgroud)

参考文献: