Socket.io ग्राहक: एक हैंडलर के साथ सभी घटनाओं का जवाब?


83

क्या प्रत्येक घटना को व्यक्तिगत रूप से निर्दिष्ट किए बिना सभी घटनाओं के लिए सॉकेट.आईओ क्लाइंट का जवाब देना संभव है?

उदाहरण के लिए, कुछ इस तरह (जो स्पष्ट रूप से अभी काम नहीं करता है):

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?
});

मैं चाहता हूं कि इस कॉलबैक फ़ंक्शन को तब बुलाया जाए जब क्लाइंट-साइड सॉकेट.आईओ कोड द्वारा किसी भी / सभी घटनाओं को प्राप्त किया जाए।

क्या यह संभव है? कैसे?


मैंने सभी ईवेंट प्रकारों को अग्रेषित करने पर निम्नलिखित समस्या को खोला, मैं उन समाधानों को भी जोड़ रहा हूं जो मुझे मिले: github.com/Automattic/socket.io/issues/1715
पीटर यूथोवेन

जवाबों:


25

यह एक शब्दकोश में सॉकेट.आईओ लाइब्रेरी स्टोर की तरह दिखता है। इस प्रकार, ऐसा नहीं लगता कि स्रोत को संशोधित किए बिना यह संभव होगा।

से स्रोत :

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;
  };


2019 में मुझे नहीं लगता कि अब ऐसा है।
उर्सक्वायरेल

82

सॉकेट के लिए अद्यतित समाधान ।io- क्लाइंट 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);
});

मेरे लिए काम किए गए उत्तरों में से कोई भी काम नहीं किया, हालांकि माथियास हॉफ और मरोस पिक्सेल में से एक करीब आया, यह मेरा समायोजित संस्करण है।

नोट: यह केवल कस्टम ईवेंट को जोड़ता है, कनेक्ट / डिस्कनेक्ट नहीं करता है


2
धन्यवाद, इससे मुझे गुमशुदा घटनाओं पर बहस करने में मदद मिली!
मैत्रेय

1
दुर्भाग्य से 'उपयोगकर्ता। *' जैसी चीजों के साथ काम नहीं कर रहा है; शायद मैं इसे लागू करने का प्रबंधन कर सकता हूं।
C4d

नमस्ते, बहुत अच्छा है, लेकिन यह मददगार हो सकता है अगर आपके पास कुछ आउटपुट उदाहरण हो सकते हैं ^ ^ मुझे लगता है कि मुझे आपके उत्तर को समझने के लिए कोड चलाने की आवश्यकता है :)
538ROMEO

24

अंत में , सॉकेट.आईओ-वाइल्डकार्ड नामक एक मॉड्यूल है जो क्लाइंट और सर्वर साइड पर वाइल्डकार्ड का उपयोग करने की अनुमति देता है

var io         = require('socket.io')();
var middleware = require('socketio-wildcard')();

io.use(middleware);

io.on('connection', function(socket) {
  socket.on('*', function(){ /* … */ });
});

io.listen(8000);

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));
});

इस तरह की घटनाओं पकड़ेगा connecting, connect, disconnect, reconnectingभी, तो ले देखभाल करते हैं।


सॉकेट.आईओ.जेएस बिल्ड: 0.9.10, विकास।
कौस्तुभ करकरे १४'१२ को

3
क्या यह एक रिलीज में खत्म हो गया?
हैकलीक्रेक

9

नोट: यह उत्तर केवल सॉकेट के लिए मान्य है। 0. 0. x

आप सॉकेट को ओवरराइड कर सकते हैं । $ 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));
});

कॉल करने से पहले aync ऑपरेशन पर कोई सलाह। setTimeout (फ़ंक्शन () {original_ $ emit.apply (सॉकेट, ['*]। concat (args)), अगर (मूल_ $ emit.apply (सॉकेट, तर्क)) {original_ $ emit.apply (सॉकेट,] 'डिफ़ॉल्ट']; कॉनकट (args));}}, 2000);
1948 को Enki

मैं Socket.IO 1.3.6 का उपयोग कर रहा है और वहाँ में एक $ फेंकना तरीका हो प्रतीत नहीं होता है socketअब
raimohanska

वास्तव में। 1.x संस्करणों के लिए @Flion उत्तर की जाँच करें
leszek.hanusz

7

मौजूदा (अप्रैल 2013) GitHub उजागर घटनाओं पर डॉक्टर एक उल्लेख है socket.on('anything')। ऐसा प्रतीत होता है कि 'कुछ भी' एक कस्टम इवेंट नाम के लिए एक प्लेसहोल्डर है, न कि एक वास्तविक कीवर्ड जो किसी भी ईवेंट को पकड़ता है।

मैंने अभी वेब सॉकेट्स और Node.JS के साथ काम करना शुरू किया है, और तुरंत किसी भी घटना को संभालने की जरूरत थी, साथ ही यह भी पता लगाने के लिए कि क्या इवेंट भेजे गए थे। काफी विश्वास नहीं कर सकता कि यह कार्यक्षमता सॉकेट से गायब है।


5

सॉकेट.-क्लाइंट 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)
  }
})

संदर्भ:


3

नहीं है के बारे में इस विषय के लिए एक लंबे चर्चा Socket.IO भंडार मुद्दा पेज पर चल रहा है। वहाँ समाधान की एक किस्म तैनात हैं (जैसे, EventEmitter EventEmitter2 के साथ)। lmjabreu ने कुछ हफ़्ते पहले एक और समाधान जारी किया: एक npm मॉड्यूल जिसे सॉकेट.आईओ-वाइल्डकार्ड कहा जाता है जो सॉकेट.आईओ (वर्तमान सॉकेट.आईओ, ~ 0.9.14 के साथ काम करता है) पर वाइल्डकार्ड इवेंट में पैच करता है।


4
लेकिन वह केवल सर्वरसाइड है ... उसका मॉड्यूल क्लाइंटसाइड (ब्राउज़र) पर प्रयोग करने योग्य नहीं है
सैंडर

3

क्योंकि आपका प्रश्न एक समाधान के लिए पूछने में बहुत सामान्य था, मैं इसे एक हैक करूंगा जिसके लिए कोड हैक करने की आवश्यकता नहीं है, बस आप सॉकेट का उपयोग कैसे करते हैं, इसमें एक बदलाव।

मैंने अभी फैसला किया है कि मेरा क्लाइंट ऐप ठीक उसी घटना को भेजेगा, लेकिन एक अलग पेलोड के साथ।

socket.emit("ev", { "name" : "miscEvent1"} );
socket.emit("ev", { "name" : "miscEvent2"} );

और सर्वर पर, कुछ इस तरह ...

socket.on("ev", function(eventPayload) {
   myGenericHandler(eventPayload.name);
});

मुझे नहीं पता कि हमेशा एक ही घटना का उपयोग करने से कोई समस्या हो सकती है, हो सकता है कि पैमाने पर किसी तरह का टकराव हो, लेकिन इससे मेरे उद्देश्य ठीक हो गए।


2

हालांकि यह एक पुराना प्रश्न है, लेकिन मुझे देशी सॉकेट का उपयोग करने में एक ही समस्या है और हल किया गया है Node.js, जिसमें .on ('डेटा') की घटना है, हर बार कुछ डेटा आने पर निकाल दिया जाता है। तो यह वही है जो मैंने अभी तक किया है:

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');
})

1

मेरे द्वारा पाए गए सभी तरीकों (सॉकेट.-वाइल्डकार्ड और सॉकेटियो-वाइल्डकार्ड सहित) ने मेरे लिए काम नहीं किया। जाहिरा तौर पर सॉकेट में कोई $ emit.io 1.3.5 नहीं है ...

सॉकेट.आईओ कोड पढ़ने के बाद, मैंने निम्नलिखित काम किया जो डीआईडी ​​काम करता है:

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
};

यह दूसरों के लिए भी एक समाधान हो सकता है। हालाँकि, ATM मुझे ठीक से समझ नहीं आ रहा है कि किसी और को मौजूदा "समाधान" के साथ समस्या क्यों है? कोई विचार? शायद यह मेरा पुराना नोड संस्करण है (0.10.31) ...


मैं यह पुष्टि कर सकता हूं कि यह काम करता है और, जैसा कि आपने देखा, केवल एक ही है जो काम करता है (इस अर्थ में: मेरे लिए भी)। आपका बहुत बहुत धन्यवाद!
मार्क

1

@ माथियास होफ का जवाब

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
};

0

मैं 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}]`);
  }
});

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.