本多@hakobera です。 以前に xhr-polling で動かした記憶があったのでおかしいなと思い、 調べてみたら、これ、socket.io-client のバグですね。
2つのバグが混ざっています。(2つ目は仕様かもしれませんが) 1つ目は node 上での XHR の check メソッド内のバグ。 具体的には、v0.9.3 で以下のコミットが入ったためです。 https://github.com/LearnBoost/socket.io-client/commit/b8c3f799363075d6ea9c2065cac59a58d660d7e4 0.9.10 だと少し変数名が変わっていますが、以下の行です。 https://github.com/LearnBoost/socket.io-client/blob/master/lib/transports/xhr.js#L193 node 環境だと global.location が undefined であるために例外が発生し、 XHR.check() が常に false を返すため、Socket の生成に失敗し、コネクションが張れない(socket.js の225行目で connect_failed イベントが発生する)ので、最終的に timeout してしまうのです。 https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L225 これに関しては既に pull-request も上がっていますね。全然取り込まれないですけど。 https://github.com/LearnBoost/socket.io-client/pull/420 なので、現時点での対応策としては、 1. 負荷テスト側では socket.io-client の 0.9.2 を使う 2. socket.io-client を fork して修正したものを使う(修正方法は上記 pull request を参照) 3. socket.io-client が修正されるのを待つ のいずれかになると思います。 2つ目のバグ(仕様?)は、 io.connect の option で transports を1つしか指定しなくても、 io.transports の設定が混ざりこんでしまうという問題です。 transport 固定しているのに以下の動きがおかしいなと思ったのです。 > xhr-polling指定 --> 指定なし (websocketに切り替わって動作) でも、実際にやってみたら、確かに websocket に切り替わるので、調べてみると、 Socket.transports のデフォルト値に io.transports が指定されており、 これが [ 'xhr-polling', 'websocket' ] という値であるためでした。 https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L23-42 指定された option.transports も merge しているのですが、 io.util.merge の実装で配列の merge は要素の追加なので、websocket という値が残ってしまい、server 側が websocket 優先の設定になっていると、そちらで繋がってしまう、という状況でした。 これも socket.js の実装が以下のようになっていれば良いと思うんですが this.options = { ... , transports: options.transports ? [] : io.transports ... } なっていないので、以下のように io.connect() を呼び出す直前で、 io.transports を書き換えることで一応回避できます。 var io = require('socket.io-client'); io.transports = ['xhr-polling']; var socket_xhr = io.connect(uri, { 'try multiple transports': false, 'force new connection': true }); io.transports = ['websocket']; var socket_ws = io.connect(uri, { 'try multiple transports': false, 'force new connection': true }); もしくは server 側の transports の優先順位を xhr-polling -> websocket の順番にするかですね。 2012年8月28日 2:14 atsuya <[email protected]>: > こんにちは、高木です。 > > "force new connection"オプションは指定されましたか? > > - 高木 > > > 2012/8/27 uchida75cm <[email protected]>: >> @hakoberaさん >> やりたい負荷テストは、おしえて頂いた方法で実現できそうです! >> ありがとうございます。 >> >> socket.io-clients側のtransportのoptionを指定してみたのですが、 >> うまくxhr-pollingで接続できず、タイムアウトになってしまう状況です。 >> >> 環境は下記のような環境です。 >> OS: CentOS release 5.7 (Final) >> Node: v0.6.19 >> Socket.IO: v0.9.10 >> Socket.IO-Client: v0.9.10 >> >> いくつか試したパターンは下記のような結果でした。 >> client --> server >> 指定なし --> 指定なし (websocketで問題なく動作) >> 指定なし --> xhr-polling指定 (タイムアウト) >> xhr-polling指定 --> 指定なし (websocketに切り替わって動作) >> xhr-polling指定 --> xhr-polling指定 (タイムアウト) >> >> ※ 動作したと判断している場合は、「任意に指定しているイベントのやりとりができた」 >> という状態です。 >> ※ タイムアウトになる場合も、server側のログでは、authorizationを通り、 >> socket.idが発行されているようでした。 >> >> nodeやmoduleのバージョンでうまく動いていないかもしれないので、 >> バージョンなどを変えてもう少し触ってみます。ソースなども少し追ってみます。 >> >> 何か進展があればまたこちらに書きたいと思います。 >> また相談させて頂くかもしれませんが、よろしくお願いします。 >> >> >> >> >> >> >> >> 2012年8月27日月曜日 16時48分03秒 UTC+9 hakobera: >>> >>> 本多@hakobera です。 >>> >>> 複数の transport が混在した環境をテストしたいというのであれば、 >>> transport 層を固定したクライアントを option 指定で別々に作れば良いのではないでしょうか。 >>> >>> var uri = 'http://domain.com'; >>> >>> // for WebSocket >>> var socket_ws = io.connect(uri, { >>> transports: [ 'websocket' ], >>> 'force new connection': true >>> }); >>> >>> // for XHR-Polling >>> var socket_xhr = io.connect(uri, { >>> transports: [ 'xhr-polling' ], >>> 'force new connection': true >>> }); >>> >>> 各オプションの詳細は以下を参照してください。 >>> https://github.com/LearnBoost/socket.io-client#options >>> >>> force new connection はマニュアルに書いてないですが、 >>> これ書かないと、同じURLの場合にコネクションが使いまわされてしまい、 >>> 何個ソケット作っても実質1クライアントで負荷テストになりまし、 >>> 2つめ以降の options の設定が効きません。 >>> >>> >>> https://github.com/LearnBoost/socket.io-client/blob/master/lib/io.js#L192-200 >>> >>> 2012年8月27日 16:21 uchida75cm <[email protected]>: >>> > こんにちは、uchida75cmといいます。 >>> > >>> > Socket.IOサーバを使ったサービスの負荷テストをしたいと考えています。 >>> > transportsがwebsocketだけの場合には、socket.io-clientsなどで、 >>> > 複数接続を行い、検証することができるかと思うのですが。 >>> > >>> > IEなど、xhr-pollingを利用するブラウザが混ざってくるような場合の環境を >>> > シミュレーションして、負荷テストする方法はないでしょうか。 >>> > >>> > 何か良い方法があればご教授いただけると幸いです。 >>> > よろしくお願いします。 >>> > >>> > -- >>> > >>> > >>> > >> >> -- >> >> >> > > -- > > > --
