Возможно ли, чтобы клиент 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?
});
Я хочу, чтобы эта функция обратного вызова вызывалась, когда клиентский код socket.io получает какие-либо / все события.
Это возможно? Как?
javascript
events
socket.io
Дерик Бейли
источник
источник
Ответы:
Похоже, что библиотека 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; };
источник
Обновленное решение для 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 };
Используйте так:
socket.on("*",function(event,data) { console.log(event); console.log(data); });
Ни один из ответов не сработал для меня, хотя ответ Матиаса Хопфа и Мароса Пикселя был близок, это моя скорректированная версия.
ПРИМЕЧАНИЕ: это фиксирует только пользовательские события, а не подключение / отключение и т. Д.
источник
Наконец , есть модуль под названием 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);
источник
Ну вот ...
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)); });
Это позволит отлавливать события , как
connecting
,connect
,disconnect
,reconnecting
тоже, так что не все равно берут.источник
Примечание: этот ответ действителен только для 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)); });
источник
socket
больше нет метода $В текущем (апрель 2013 г.) документе GitHub по раскрытым событиям упоминается файл
socket.on('anything')
. Похоже, что «что-нибудь» является заполнителем для имени настраиваемого события, а не фактическим ключевым словом, которое могло бы уловить любое событие.Я только начал работать с веб-сокетами и Node.JS, и мне сразу понадобилось обработать любое событие, а также выяснить, какие события были отправлены. Не могу поверить, что эта функция отсутствует в socket.io.
источник
socket.io-client 1.7.3
По состоянию на май 2017 года ни одно из других решений не могло работать так, как я хотел - сделал перехватчик, использующий в 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) } })
Рекомендации:
источник
На странице проблемы репозитория Socket.IO ведется долгое обсуждение этой темы . Там опубликовано множество решений (например, переопределение EventEmitter с помощью EventEmitter2). Пару недель назад lmjabreu выпустил другое решение: модуль npm под названием socket.io-wildcard, который исправляет событие подстановочного знака в Socket.IO (работает с текущим Socket.IO, ~ 0.9.14).
источник
Поскольку ваш вопрос был довольно общим, предлагая решение, я предлагаю тот, который не требует взлома кода, просто изменение того, как вы используете сокет.
Я просто решил, что мое клиентское приложение будет отправлять точно такое же событие, но с другой полезной нагрузкой.
socket.emit("ev", { "name" : "miscEvent1"} ); socket.emit("ev", { "name" : "miscEvent2"} );
А на сервере что-то вроде ...
socket.on("ev", function(eventPayload) { myGenericHandler(eventPayload.name); });
Я не знаю, может ли постоянное использование одного и того же события вызвать какие-либо проблемы, возможно, столкновения какого-то масштаба, но это отлично послужило моим целям.
источник
Несмотря на то, что это старый вопрос, у меня та же проблема, и я решил ее с помощью собственного сокета, в
Node.js
котором есть событие .on ('data'), запускаемое каждый раз, когда приходят какие-то данные. Вот что я сделал до сих пор: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'); })
источник
Все найденные мной методы (включая socket.io-wildcard и socketio-wildcard) у меня не работали. Видимо в socket.io 1.3.5 нет $ emit ...
После прочтения кода socket.io я исправил следующее, что ДЕЙСТВИТЕЛЬНО работает:
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 };
Это может быть решением и для других. Тем не менее, банкомат. Я не совсем понимаю, почему, похоже, ни у кого нет проблем с существующими «решениями»?!? Есть идеи? Может, это моя старая версия узла (0.10.31) ...
источник
@Matthias Hopf ответ
Обновленный ответ для v1.3.5. Была ошибка с аргументами, если вы хотите слушать старое событие и
*
событие вместе.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 };
источник
Я использую Angular 6 и пакет npm: ngx-socket-io
import { Socket } from "ngx-socket-io";
...
constructor(private socket: Socket) { }
...
После подключения сокета я использую этот код, он обрабатывает все настраиваемые события ...
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}]`); } });
источник
Как и в документации v3.0 :
socket.onAny((event, ...args) => { console.log(`got ${event}`); });
источник