2012-05-01 5 views
60

各イベントを個別に指定することなく、すべてのイベントにsocket.ioクライアントが応答できるようにすることはできますか?例えばSocket.ioクライアント:1つのハンドラですべてのイベントに応答しますか?

、(明らかに今は動作しません)このような何か:私は任意の/すべてのイベントは、クライアント側のソケットによって受信されたときに、このコールバック関数が呼び出されるようにしたい

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

。 ioコード。

これは可能ですか?どうやって?

+0

を私がオープンすべてのイベントタイプを転送する際の問題に続き、見つけたソリューションも追加しています。 https://github.com/Automattic/socket.io/issues/1715 –

答えて

19

socket.ioライブラリはこれらを辞書に格納しているようです。したがって、ソースを変更せずにこれが可能であるとは思わないでください。 sourceから

:ここに行く

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

もこれを見つけました:http:// stackoverflow。com/questions/8832414/overriding-socket-ios-emit-and-on/8838225 –

10

...

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

これは、あまりにもconnectingconnectdisconnectreconnectingなどのイベントをキャッチし、その世話を行います。

+0

Socket.IO.jsビルド:0.9.10、開発。 –

+3

これはリリースで終了しましたか? – hacklikecrack

7

現在(2012年4月)GitHub doc on exposed eventsにはsocket.on('anything')が記載されています。 「何か」はカスタムイベント名のプレースホルダーで、実際のキーワードではイベントを捕まえることはできません。

私はちょうどウェブソケットとのNode.jsでの作業を開始し、すぐに任意のイベントを処理するだけでなく、送信されたかの事象を発見する必要がありました。この機能がsocket.ioにないとは思えません。

3

a long discussion about this topicがSocket.IOリポジトリの問題ページで行われています。投稿されたさまざまなソリューションがあります(たとえば、EventEmitterをEventEmitter2でオーバーライドするなど)。 lmjabreuは数週間前に別の解決策をリリースしました。ワームカードイベントでSocket.IOにパッチを当てるsocket.io-wildcardと呼ばれるnpmモジュール(現在のSocket.IO、〜0.9.14で動作します)。

+3

これはサーバ側のみです...彼のモジュールはclientside(ブラウザ)で使用できません – Sander

9

注:この答えはあなたがソケットを上書きすることができsocket.io 0.xで

に対してのみ有効です$次のコードでは

を発する次の2つの新しい機能を持っていた:

  • トラップすべてのイベント
  • 古いメソッドでトラップされていないイベント(デフォルトのリスナー)
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)); 
}); 
+0

呼び出しの前にayncオペレーションに関するアドバイスが適用されます。 \tのsetTimeout(関数(){ \t \t \t \t original_ $ emit.apply(ソケット、[ '*'] CONCAT(引数));。 \t \t \t \t(original_ $ emit.apply(ソケット、引数)であれば! ){ \t \t \t \t \t original_ $ emit.apply(ソケット、[ 'デフォルト']連結(引数)); \t \t \t \t} \t \t \t}、2000); – Enki

+0

私はSocket.IO 1.3.6を使用していて、 'socket'に$ emitメソッドがないようです。 – raimohanska

+0

確かに。 @Flionの1.xバージョンの回答を確認してください –

1

(socket.io-ワイルドカードとsocketio-ワイルドカードを含む)私が見つけたすべてのメソッドは私のために動作しませんでした。どうやら何$ソケットを読んだ後... socket.io 1.3.5に

が放出されていません。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 
}; 

これは他の人のための解決策かもしれません。しかし、ATMは、他の誰も既存の "ソリューション"に問題があるように見えない理由を正確には理解していませんか?何か案は?おそらくそれは私の古いノードのバージョン(0.10.31)...

+0

私はそれがうまく動作することを確認できます。ご存知のように、動作するのは唯一のものです(意味では私にとっても)。どうもありがとうございました! – mark

3

あなたの質問は解決策を求めるのにかなり一般的だったので、私はコードをハッキングする必要はないが、あなたの使い方を変更するだけですソケット。

私は、クライアントアプリケーションがまったく同じイベントを送信するが、ペイロードが異なることを決めたばかりです。

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

とサーバ上の、何かのよう...

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

私はいつも同じイベントを使用すると、スケールですべての問題、いくつかの種類の多分衝突を引き起こす可能性がある場合は知っているが、これはありませんちょうど私の目的を果たした。

1

@Matthiasホップは

v1.3.5のための答えを更新しまし答えます。古いイベントと*イベントを一緒に聞きたい場合、argsのバグがありました。このようなsocket.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 
}; 

使用のための

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

更新ソリューション:

socket.on("*",function(event,data) { 
    console.log(event); 
    console.log(data); 
}); 

回答のいずれもの一つが、私のために働いていませんMathias HopfとMaros Pixelが近づいてきました。これは私が調整したバージョンです。

注:最後にこれが唯一の接続しない/切り離し、カスタムイベントをキャッチするなど

+2

ありがとう、これは私に不足しているイベントをデバッグするのに役立ちました! – Maitreya

+2

これは完璧に動作しました - ありがとう! – Jonathan

+1

残念ながら、 'user。*';のようなもので作業していません。たぶん私はそれを実装することができます。 – C4u

12

、クライアントとサーバー側で

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

io.use(middleware); 

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

io.listen(8000); 
+0

は完全に動作します – tinybyte

2

をワイルドカードを使用できますsocket.io-wildcardと呼ばれるモジュールがありますsocket.io-client 1.7.3

現在、2017年5月現在、他のソリューションは、私が望んでいた非常にどのように動作する - テスト目的のみのための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) 
    } 
}) 

参考文献:

関連する問題