Czy możliwe jest, aby klient socket.io odpowiadał na wszystkie zdarzenia bez określania każdego zdarzenia indywidualnie?
Na przykład coś takiego (co oczywiście teraz nie działa):
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?
});
Chcę, aby ta funkcja zwrotna była wywoływana, gdy jakiekolwiek / wszystkie zdarzenia zostaną odebrane przez kod socket.io po stronie klienta.
czy to możliwe? W jaki sposób?
javascript
events
socket.io
Derick Bailey
źródło
źródło
Odpowiedzi:
Wygląda na to, że biblioteka socket.io przechowuje je w słowniku. W związku z tym nie myśl, że byłoby to możliwe bez modyfikacji źródła.
Ze źródła :
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; };
źródło
Zaktualizowane rozwiązanie dla 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 };
Użyj w ten sposób:
socket.on("*",function(event,data) { console.log(event); console.log(data); });
Żadna z odpowiedzi nie zadziałała dla mnie, chociaż ta autorstwa Mathiasa Hopfa i Marosa Pixela była bliska, to jest moja dostosowana wersja.
UWAGA: to przechwytuje tylko zdarzenia niestandardowe, a nie łączy / rozłącza itp
źródło
Wreszcie istnieje moduł o nazwie socket.io-wildcard, który umożliwia używanie symboli wieloznacznych po stronie klienta i serwera
var io = require('socket.io')(); var middleware = require('socketio-wildcard')(); io.use(middleware); io.on('connection', function(socket) { socket.on('*', function(){ /* … */ }); }); io.listen(8000);
źródło
Proszę bardzo ...
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)); });
Będzie to złapać wydarzeń, takich jak
connecting
,connect
,disconnect
,reconnecting
zbyt, więc dbać.źródło
Uwaga: ta odpowiedź jest ważna tylko dla socket.io 0.x
Możesz nadpisać socket. $ Emit
Z poniższym kodem masz dwie nowe funkcje do:
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)); });
źródło
socket
już metody $Bieżący dokument GitHub (z kwietnia 2013 r.) Dotyczący ujawnionych zdarzeń wspomina o
socket.on('anything')
. Wygląda na to, że „cokolwiek” jest symbolem zastępczym nazwy wydarzenia niestandardowego, a nie faktycznym słowem kluczowym, które mogłoby wyłapać dowolne wydarzenie.Właśnie zacząłem pracować z gniazdami internetowymi i Node.JS i od razu musiałem obsłużyć każde zdarzenie, a także dowiedzieć się, jakie zdarzenia zostały wysłane. Nie mogę uwierzyć, że tej funkcji brakuje w socket.io.
źródło
socket.io-client 1.7.3
W maju 2017 nie mogłem sprawić, by żadne z innych rozwiązań działało tak, jak chciałem - stworzyłem przechwytywacz, używając na Node.js wyłącznie do celów testowych:
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) } })
Bibliografia:
źródło
Na stronie dotyczącej repozytorium Socket.IO toczy się długa dyskusja na ten temat . Istnieje wiele opublikowanych tam rozwiązań (np. Zastąpienie EventEmitter przez EventEmitter2). lmjabreu wydało inne rozwiązanie kilka tygodni temu: moduł npm o nazwie socket.io-wildcard, który łata zdarzenie wieloznaczne na Socket.IO (działa z obecnym Socket.IO, ~ 0.9.14).
źródło
Ponieważ twoje pytanie było dość ogólne, prosząc o rozwiązanie, przedstawię to, które nie wymaga hakowania kodu, a jedynie zmianę sposobu korzystania z gniazda.
Właśnie zdecydowałem, że moja aplikacja kliencka będzie wysyłać dokładnie to samo zdarzenie, ale z innym ładunkiem.
socket.emit("ev", { "name" : "miscEvent1"} ); socket.emit("ev", { "name" : "miscEvent2"} );
A na serwerze coś w rodzaju ...
socket.on("ev", function(eventPayload) { myGenericHandler(eventPayload.name); });
Nie wiem, czy używanie tego samego zdarzenia zawsze może powodować jakieś problemy, może jakieś kolizje na dużą skalę, ale to służyło moim celom.
źródło
Chociaż jest to stare pytanie, mam ten sam problem i rozwiązałem go za pomocą natywnego gniazda in
Node.js
, które ma zdarzenie .on ('data'), uruchamiane za każdym razem, gdy przychodzą jakieś dane. Oto, co zrobiłem do tej pory: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'); })
źródło
Wszystkie znalezione metody (w tym socket.io-wildcard i socketio-wildcard) nie działały dla mnie. Najwyraźniej nie ma $ emitowanego w socket.io 1.3.5 ...
Po przeczytaniu kodu socket.io załatałem następujące, które DZIAŁAły:
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 };
To może być rozwiązanie również dla innych. Jednak bankomat nie do końca rozumiem, dlaczego nikt inny nie ma problemów z istniejącymi „rozwiązaniami”?!? Jakieś pomysły? Może to moja stara wersja węzła (0.10.31) ...
źródło
@Matthias Hopf odpowiedz
Zaktualizowana odpowiedź dla wersji 1.3.5. Wystąpił błąd z argumentami, jeśli chcesz słuchać razem starego wydarzenia i
*
wydarzenia.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 };
źródło
Używam Angular 6 i pakietu npm: ngx-socket-io
import { Socket } from "ngx-socket-io";
...
constructor(private socket: Socket) { }
...
Po podłączeniu gniazda używam tego kodu, to obsługuje wszystkie zdarzenia niestandardowe ...
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}]`); } });
źródło
Tak jak w dokumentacji v3.0 :
socket.onAny((event, ...args) => { console.log(`got ${event}`); });
źródło