Ist es möglich, dass ein socket.io-Client auf alle Ereignisse reagiert, ohne jedes Ereignis einzeln angeben zu müssen?
Zum Beispiel so etwas (was momentan offensichtlich nicht funktioniert):
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?
});
Ich möchte, dass diese Rückruffunktion aufgerufen wird, wenn alle Ereignisse vom clientseitigen socket.io-Code empfangen werden.
Ist das möglich? Wie?
javascript
events
socket.io
Derick Bailey
quelle
quelle
Antworten:
Es sieht so aus, als ob die Bibliothek socket.io diese in einem Wörterbuch speichert. Denken Sie daher nicht, dass dies möglich wäre, ohne die Quelle zu ändern.
Aus der Quelle :
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; };
quelle
Aktualisierte Lösung für 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 };
Verwenden Sie wie folgt:
socket.on("*",function(event,data) { console.log(event); console.log(data); });
Keine der Antworten hat bei mir funktioniert, obwohl die von Mathias Hopf und Maros Pixel nahe kam, ist dies meine angepasste Version.
HINWEIS: Dies fängt nur benutzerdefinierte Ereignisse ab, nicht das Verbinden / Trennen usw.
quelle
Schließlich gibt es ein Modul namens socket.io-wildcard , mit dem Platzhalter auf Client- und Serverseite verwendet werden können
var io = require('socket.io')(); var middleware = require('socketio-wildcard')(); io.use(middleware); io.on('connection', function(socket) { socket.on('*', function(){ /* … */ }); }); io.listen(8000);
quelle
Bitte schön ...
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)); });
Dies wird fangen Veranstaltungen wie
connecting
,connect
,disconnect
,reconnecting
zu, so tun kümmern.quelle
Hinweis: Diese Antwort gilt nur für socket.io 0.x.
Sie können Socket überschreiben . $ Emit
Mit dem folgenden Code haben Sie zwei neue Funktionen:
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)); });
quelle
socket
Das aktuelle GitHub-Dokument (April 2013) zu exponierten Ereignissen erwähnt a
socket.on('anything')
. Es scheint, dass 'irgendetwas' ein Platzhalter für einen benutzerdefinierten Ereignisnamen ist, kein tatsächliches Schlüsselwort, das ein Ereignis abfangen würde.Ich habe gerade angefangen, mit Web-Sockets und Node.JS zu arbeiten, und musste sofort jedes Ereignis behandeln und herausfinden, welche Ereignisse gesendet wurden. Ich kann nicht glauben, dass diese Funktionalität in socket.io fehlt.
quelle
socket.io-client 1.7.3
Ab Mai 2017 konnte keine der anderen Lösungen so funktionieren, wie ich es wollte - einen Interceptor erstellt, der bei Node.js nur zu Testzwecken verwendet wurde:
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) } })
Verweise:
quelle
Es gibt eine lange Diskussion zu diesem Thema auf der Socket.IO-Repository-Problemseite. Dort werden verschiedene Lösungen veröffentlicht (z. B. Überschreiben von EventEmitter mit EventEmitter2). lmjabreu hat vor ein paar Wochen eine andere Lösung veröffentlicht: ein npm-Modul namens socket.io-wildcard , das ein Wildcard-Ereignis auf Socket.IO patcht (funktioniert mit dem aktuellen Socket.IO, ~ 0.9.14).
quelle
Da Ihre Frage bei der Frage nach einer Lösung ziemlich allgemein war, werde ich diese Frage stellen, bei der der Code nicht gehackt werden muss, sondern lediglich die Verwendung des Sockets geändert wird.
Ich habe gerade beschlossen, dass meine Client-App genau dasselbe Ereignis sendet, jedoch mit einer anderen Nutzlast.
socket.emit("ev", { "name" : "miscEvent1"} ); socket.emit("ev", { "name" : "miscEvent2"} );
Und auf dem Server so etwas wie ...
socket.on("ev", function(eventPayload) { myGenericHandler(eventPayload.name); });
Ich weiß nicht, ob die Verwendung des gleichen Ereignisses zu Problemen führen kann, möglicherweise zu Kollisionen in größerem Maßstab, aber dies diente meinen Zwecken in Ordnung.
quelle
Alle Methoden, die ich gefunden habe (einschließlich socket.io-wildcard und socketio-wildcard), haben bei mir nicht funktioniert. Anscheinend gibt es kein $ emit in socket.io 1.3.5 ...
Nachdem ich den Code von socket.io gelesen hatte, habe ich Folgendes gepatcht, was funktioniert hat:
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 };
Dies könnte auch eine Lösung für andere sein. Allerdings verstehe ich Geldautomaten nicht genau, warum sonst niemand Probleme mit den vorhandenen "Lösungen" zu haben scheint?!? Irgendwelche Ideen? Vielleicht ist es meine alte Knotenversion (0.10.31) ...
quelle
@ Matthias Hopf Antwort
Aktualisierte Antwort für v1.3.5. Es gab einen Fehler mit Argumenten, wenn Sie alte Ereignisse und
*
Ereignisse gemeinsam anhören möchten .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 };
quelle
Obwohl dies eine alte Frage ist, habe ich das gleiche Problem und habe es mit dem nativen Socket in gelöst, der
Node.js
das Ereignis .on ('data') enthält und jedes Mal ausgelöst wird, wenn einige Daten eingehen. Das habe ich bisher gemacht: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'); })
quelle
Ich verwende Angular 6 und das npm-Paket: ngx-socket-io
import { Socket } from "ngx-socket-io";
...
constructor(private socket: Socket) { }
...
Nach dem Anschließen des Sockets verwende ich diesen Code, der alle benutzerdefinierten Ereignisse behandelt ...
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}]`); } });
quelle