¿Es posible que un cliente socket.io responda a todos los eventos sin tener que especificar cada evento individualmente?
Por ejemplo, algo como esto (que obviamente no funciona en este momento):
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?
});
Quiero que se llame a esta función de devolución de llamada cuando el código socket.io del lado del cliente reciba cualquiera o todos los eventos.
es posible? ¿Cómo?
javascript
events
socket.io
Derick Bailey
fuente
fuente
Respuestas:
Parece que la biblioteca socket.io los almacena en un diccionario. Como tal, no crea que esto sería posible sin modificar la fuente.
De la fuente :
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; };
fuente
Solución actualizada para 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 };
Use así:
socket.on("*",function(event,data) { console.log(event); console.log(data); });
Ninguna de las respuestas me funcionó, aunque la de Mathias Hopf y Maros Pixel se acercó, esta es mi versión ajustada.
NOTA: esto solo captura eventos personalizados, no se conecta / desconecta, etc.
fuente
Finalmente , hay un módulo llamado socket.io-wildcard que permite usar comodines en el lado del cliente y del servidor
var io = require('socket.io')(); var middleware = require('socketio-wildcard')(); io.use(middleware); io.on('connection', function(socket) { socket.on('*', function(){ /* … */ }); }); io.listen(8000);
fuente
Aqui tienes ...
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)); });
Esto cogerá eventos como
connecting
,connect
,disconnect
,reconnecting
también, así que cuidar su toma.fuente
Nota: esta respuesta solo es válida para socket.io 0.x
Puede anular socket. $ Emit
Con el siguiente código tienes dos nuevas funciones para:
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)); });
fuente
socket
másEl documento de GitHub actual (abril de 2013) sobre eventos expuestos menciona a
socket.on('anything')
. Parece que "cualquier cosa" es un marcador de posición para un nombre de evento personalizado, no una palabra clave real que capturaría cualquier evento.Acabo de comenzar a trabajar con sockets web y Node.JS, e inmediatamente tuve la necesidad de manejar cualquier evento, así como descubrir qué eventos se enviaron. No puedo creer que esta funcionalidad falte en socket.io.
fuente
socket.io-client 1.7.3
A partir de mayo de 2017, no podía hacer que ninguna de las otras soluciones funcionara como quería: hice un interceptor, utilizándolo en Node.js solo con fines de prueba:
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) } })
Referencias:
fuente
Hay una larga discusión sobre este tema en la página de problemas del repositorio de Socket.IO. Hay una variedad de soluciones publicadas allí (por ejemplo, anular EventEmitter con EventEmitter2). lmjabreu lanzó otra solución hace un par de semanas: un módulo npm llamado socket.io-wildcard que se parchea en un evento comodín en Socket.IO (funciona con el Socket.IO actual, ~ 0.9.14).
fuente
Debido a que su pregunta fue bastante general al pedir una solución, presentaré esta que no requiere piratear el código, solo un cambio en la forma en que usa el socket.
Decidí que mi aplicación cliente enviara exactamente el mismo evento, pero con una carga útil diferente.
socket.emit("ev", { "name" : "miscEvent1"} ); socket.emit("ev", { "name" : "miscEvent2"} );
Y en el servidor, algo como ...
socket.on("ev", function(eventPayload) { myGenericHandler(eventPayload.name); });
No sé si usar siempre el mismo evento podría causar algún problema, tal vez colisiones de algún tipo a escala, pero esto cumplió mis propósitos muy bien.
fuente
Todos los métodos que encontré (incluidos socket.io-wildcard y socketio-wildcard) no funcionaron para mí. Aparentemente no hay $ emit en socket.io 1.3.5 ...
Después de leer el código socket.io, reparé lo siguiente que funcionó:
var Emitter = require('events').EventEmitter; var emit = Emitter.prototype.emit; [...] var onevent = socket.onevent; socket.onevent = function (packet) { var args = ["*"].concat (packet.data || []); onevent.call (this, packet); // original call emit.apply (this, args); // additional call to catch-all };
Esta también podría ser una solución para otros. Sin embargo, ATM no entiendo exactamente por qué nadie más parece tener problemas con las "soluciones" existentes. ¿Algunas ideas? Tal vez sea mi antigua versión de nodo (0.10.31) ...
fuente
@Matthias Hopf respuesta
Respuesta actualizada para v1.3.5. Hubo un error con los argumentos, si quieres escuchar el evento antiguo y el
*
evento juntos.var Emitter = require('events').EventEmitter; var emit = Emitter.prototype.emit; // [...] var onevent = socket.onevent; socket.onevent = function (packet) { var args = packet.data || []; onevent.call (this, packet); // original call emit.apply (this, ["*"].concat(args)); // additional call to catch-all };
fuente
Aunque esta es una pregunta antigua, tengo el mismo problema y lo resolví usando el socket nativo
Node.js
, que tiene un evento de .on ('datos'), que se activa cada vez que llegan algunos datos. Así que esto es lo que he hecho hasta ahora:const net = require('net') const server = net.createServer((socket) => { // 'connection' listener. console.log('client connected') // The stuff I was looking for socket.on('data', (data) => { console.log(data.toString()) }) socket.on('end', () => { console.log('client disconnected') }) }) server.on('error', (err) => { throw err; }) server.listen(8124, () => { console.log('server bound'); })
fuente
Estoy usando Angular 6 y el paquete npm : ngx-socket-io
import { Socket } from "ngx-socket-io";
...
constructor(private socket: Socket) { }
...
Después de conectar el enchufe, uso este código, este está manejando todos los eventos personalizados ...
const onevent = this.socket.ioSocket.onevent; this.socket.ioSocket.onevent = function (packet: any) { const args = packet.data || []; onevent.call(this, packet); // original call packet.data = ["*"].concat(args); onevent.call(this, packet); // additional call to catch-all }; this.socket.on("*", (eventName: string, data: any) => { if (typeof data === 'object') { console.log(`socket.io event: [${eventName}] -> data: [${JSON.stringify(data)}]`); } else { console.log(`socket.io event: [${eventName}] -> data: [${data}]`); } });
fuente