Socket.io: ダブルコネクト

䜜成日 2011幎08月23日  Â·  42コメント  Â·  ゜ヌス: socketio/socket.io

どういうわけか、クラむアントに二重接続が発生し぀たり、すべおのハンドラヌが2回呌び出されたす、自分で状況を再珟できたせんでしたが、バグレポヌトを受信し続けたす。既に接続されおいるずきに、socket.socket.connectを呌び出した堎合の動䜜はたったく同じです。゜ケットwebsocketずflashsocketでテスト枈み

Socket.IO client bug

最も参考になるコメント

基本的な䟋に埓っお、ただこの問題が発生しおいたす。

線集正確に正しいかどうかはわかりたせんが、修正を芋぀けたした。 基本的に必芁なのは䜿甚するこずだけです

io.once('connection', ...)

の代わりに

io.on('connection', ...)

党おのコメント42件

クむックハックずしお、「新しい接続を匷制する」を䜿甚できたす誀った構成

たた、アプリケヌションでこのバグを確認したした。
次は再珟でした。 WebSocket接続のFFで、いく぀かの゚ラヌが発生したした。 その埌、次々ず3぀の再接続むベントが生成されたした。 この埌、3぀の新しい接続が確立され、ブラりザは1぀ではなく3぀のメッセヌゞを受信したした。

たぶん、再接続ロゞックにいく぀かのバグがありたすか 1぀ではなく耇数の再接続を生成する䜕か。

WebSocketFF 3.6などをサポヌトしおいない叀いブラりザヌで、dom readyむベントjQueryの "$"でsocket.ioを初期化するず耇数の接続が発生し、埌のwindow.loadで初期化するずいう問題が発生したした。むベントはしたせん。 この特定の問題は䞀貫しお再珟可胜であるこずがわかりたした。 それがあなたが芋おいるものず同じであるかどうかはわかりたせんが、症状は非垞に䌌おいたす。

ここでも同じ問題。 問題は、サヌバヌが䜕らかの理由でクラッシュしおから電源が再びオンになった堎合、再接続するず毎回n +1の応答が発生するこずです。 したがっお、3぀のサヌバヌがクラッシュしたずするず、各サヌバヌの送信で4぀の応答が返されたす。 ペヌゞを曎新するず問題が解決したす。 誰かがこれに察する解決策を芋぀けたしたか[䞀時的であっおも]

これは氞続的な解決策ではないかもしれたせんが、各むベントが個別にバむンドされ、自動再接続で重耇の問題が解決されたように芋えるようにコヌドを再配眮したした

me.socket.on('connect', function () {
});

me.socket.on('message', function(data) {

});

me.socket.on('disconnect', function() {

});

キャッチされたWiresharkダンプを介しお1週間デバッグした埌、私はなんずか理由を芋぀けおこのバグを再珟するこずができたした。

぀たり、再接続ロゞックは非垞に壊れやすいものです。 これは、䞊行しお実行できる倚くのタむマヌに䟝存し、耇数の再接続に぀ながりたす。 この行https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L511がこのバグの䞻な理由です。

今完党に再珟

  1. クラむアントからサヌバヌに接続したす。
  2. 階乗を介しおサヌバヌにスロヌコヌドを配眮したすnode.jsメむンルヌプを4〜8秒間䞭断する必芁がありたす。
    関数fibon{
    ifn <2は1を返したす。
    fibon-2+ fibon-1;を返したす。
    }
    それをauth-sectionに入れたす。 これはハンドシェむクで呌び出す必芁がありたす。
    io.set 'authorization'、functiondata、accept{
    console.info "Fibo ::" + fibo41;
    ノヌドコン゜ヌルで実隓しお、fiboNを芋぀ける必芁がありたす。
    メむンルヌプを4〜8秒間ブロックしたす。
  3. ここで、サヌバヌを高速で再起動する必芁がありたす。
    スロヌコヌドが接続に適甚されたす。
    ハンドシェむクされおいないこずをクラむアントに通知する必芁がありたす。
    そしお今、それは再接続を詊みたす。
    コン゜ヌルでは、いく぀かの再接続の詊みが衚瀺されたす「再接続/再接続」コヌルバックにログを蚘録した堎合。
    スロヌダりンハックの埌、それは氞遠に繰り返されたす。

実生掻では、これはサヌバヌの速床䜎䞋によっお再珟されたした-少なくずも数秒間は応答しおください。
これは、node.jsの負荷が高く、応答が遅れる堎合がありたす。
たたは、䞀郚のネットワヌクの速床䜎䞋もそのような動䜜に぀ながる可胜性がありたす。
サヌバヌの再起動埌にも再珟できたす。

この行socket.js、511
self.reconnectionTimer = setTimeoutmaybeReconnect、self.reconnectionDelay;

接続呌び出し埌にむベントをスケゞュヌルしたす。 たた、接続応答が少なくずも1秒間遅延するず、接続応答がトリガヌされ、新しい再接続がキュヌに入れられたす。 2秒埌、もう1぀远加されたす。

私は修正を行いたしたが、テストされおおらず、あたりしっかりしおいないように芋えたす。 䞻な問題-maybeReconnect関数に察しおどのコヌルバック/タむマヌを同時に実行できるかを掚論する方法。
この行 https 

Socket.ioクラむアントは、ステヌトマシンを䜿甚するようにリファクタリングされる堎合、掚論がはるかに簡単になる可胜性がありたす。 珟圚、状態はさたざたなフラグ接続、接続、再接続などに分散しおいたす。 そしお、倚くの機胜で、「ifself.reconnecting」や他の倚くのガヌドを芋たした。
ステヌトマシンは、このロゞックを単玔化しお、状態ずむベントのセットを持぀こずができたす。 たた、タむマヌはむベントを発生させるためにのみ䜿甚できたす。 このむベントが誀った状態に達した堎合、ステヌトマシンはこのむベントを無芖するだけで、気にする必芁はありたせん。

JSに適したSTMは芋぀かりたせんでしたが、RubyのSTMはJSに簡単に移怍できたす https 

この問題を修埩するには、間違いなく+1したす。 私はsocket.ioたたはsocket.io-clientを盎接倉曎せずにこの問題の回避策を芋぀けようず取り組んできたしたが、残念ながら、私が確実に思い぀いた唯䞀の方法は、再接続を無効にするこずです。 これは間違いなく良い解決策ではありたせん。特にモバむルデバむスの䜿甚が増えるず、再接続は倧きな芁件になりたす。

これが開発者の優先リストにどのように含たれるかを誰かが知っおいたすか

ああ。 この問題は問題から3rd-Edenに割り圓おられおいるようです https 

クラむアントの修正を行い、プルリク゚ストを送信したした。 0.8.4で正垞に動䜜し、他のバヌゞョンでも正垞に動䜜したす。 ただし、ハンドシェむクにAJAXたたはCORSを䜿甚する゜ヌス機胜を無効にする必芁がありたす。 詳现に぀いおは、 https 

そのような叀い問題を埩掻させおすみたせん。 私はsocket.ioの最新バヌゞョンを䜿甚しおいたすたたは、少なくずも、npm install socket.ioを実行したした。 この問題はただ発生しおいたす。socket.ioずnode.jsは党䜓ずしお比范的新しいです。 たた、最初の接続䞀床にしか発生しなかった2぀のうちで読み取り゚ラヌが発生するこずがあるずいう問題もありたした。 私がクリスず蚀っおいるのが正しければ、あなたの修正はコミットされたので、もう起こらないはずですが、重芁な芁玠を芋逃さない限り、それでも起こりたすか

線集-

それはクリスフォヌクされたsocket.ioのようで、それを修正したしたが、修正は元のsocket.ioにコミットされおいたせんでしたか

@JTallis @gdizず同じ問題があり、圌の提案はうたくいきたした。 問題が類䌌しおいる堎合は、詊しおみお、どのように機胜するかをお知らせください。

最新バヌゞョンであるず私が信じおいる0.9.16でもこの問題が発生しおいたす。 gdizはこれを防ぐためにどのように回避したすか 完党には理解しおいたせんでした。

omg ...アプリの䜕が問題になっおいるのか、接続が倱われお曎新された埌にサヌバヌずクラむアント間のメッセヌゞが倧量に重耇する理由を理解するために数時間を費やしおいたす...

0.9.16を䜿甚しおこの問題を確認できたす

同じファむルnode.jsファむルで次のクラむアントずサヌバヌのコヌドを䜿甚しお、二重接続むベントを自由に取埗できたす。

"use strict";
var server = require('socket.io');
var client = require('socket.io-client');

setTimeout(function () {
    var io = server.listen(8888);

    io.of('/chat').on('connection', function (socket) {
        console.log('Server: /chat connection');
    });

    io.sockets.on('connection', function (socket) {
        console.log('Server: connection');
    });
}, 2000);

var socketAddress = 'http://localhost:8888/chat';
var socket = client.connect(socketAddress);

socket.on('connect', function () {
    console.log("Client: connect");
});

socket.on('error', function () {
    console.log("Client: error");
    socket.socket.reconnect();
});

奇劙なこずがいく぀かありたす。

1URLから「/ chat」を削陀しお名前空間接続を通垞の接続に倉曎するず、接続むベントは1぀だけになりたす。

2サヌバヌをすぐに起動し、setInterval時間をれロに倉曎するず、初期接続゚ラヌは発生せず、接続むベントは1぀だけになりたす。

これに察する回避策たたは修正はありたすか

同じ問題を抱えおいたす。 socket.ioサヌバヌが予期せず再起動した堎合、クラむアントは2回再接続するため、すべおのメッセヌゞがクラむアントによっお2回凊理されたす。 本圓にクラむアント偎で私のカりントを台無しにしたす。

1.0.0-pre2リリヌスでも同じ問題がありたす。 socket.ioを再起動するず、2぀の「400BadRequest」がありたす。

今日はこれを調べたす

今日はこれを調べたす

詳现、ログ、画面が必芁な堎合は、遠慮なく 毎回ではありたせん。

2755行目の1.0.6のクラむアントsocket.io.js

Request.prototype.create = functionisBinary、supportsBinary{
var xhr = this.xhr = new XMLHttpRequest{agentthis.agent、xdomainthis.xd};
..。
}

蚭定するのは良い考えだず思いたす
xhr.timeout = Manager._timeoutのむンスタンス-10ミリ秒
このようにしお、クラむアント偎で耇数のクラむアント゜ケットが䜜成されるのを防ぎたす。
サヌバヌ偎では、耇数の゜ケットがハヌトビヌトタむムアりトになりたす。

基本的なsocket.ioの「GettingStarted」の䟋http://socket.io/get-started/chat/には、このダブル゜ケット接続の問題がありたす。

次のいずれか確率の昇順では、単䞀のブラりザタブ接続からダブル゜ケット接続になりたす。
alocalhost3000に接続するず、最初のブラりザタブ自䜓から
blocalhost3000に接続するず、2番目のブラりザタブから
clocalhost3000に接続する前に、ブラりザコン゜ヌルを開いたたたにしたす

远加の所芋

 io.on('connection', function(socket){
    console.log('a user connected: ' + socket.id);
    socket.on('disconnect', function(){
       console.log('a user disconnected');
       console.log(socket.nickname + ' has disconnected from the chat.');
    });
});
  1. socket.id぀のブラりザタブリク゚ストから発生する2぀の異なる
  2. 「重耇」゜ケット接続は、「未定矩がチャットから切断されたした」ずいうconsole.logを䜿甚しお、玄1分で切断されたす。
  3. Express Generator 4.2Morganを䜿甚を䜿甚しおから「GettingStarted」の䟋を実装するず、「良奜な」ブラりザ接続により、「GET / 3041ms」などの1行のExpressログが生成されたす。 ただし、この「ダブル」゜ケット接続がある堎合は垞に、「GET / 3041ms」ず「GET / 2003ms-386b」の2぀の゚クスプレスログがありたす。

Mac、Chrome、Express 4.2、および最新のsocket.ioを䜿甚しおいたす。

2぀のログの䜜成にはタむミングの違いがありたす。 最初のログは、Chromeが「lo」を「 localhost3000 」に自動完了したずきに発生し、2番目のログはEnterボタンを抌したずきに発生したす。

「Xusersconnected」コン゜ヌルログメッセヌゞがあり、自分のブラりザが2぀たたは3぀のナヌザヌ接続通知をトリガヌしたずきに非垞に迷惑でした。

ここで、問題の解決策がconsole.log行をコメントアりトしたこずを告癜する必芁がありたす。 しかし、皆さん、良い仕事を続けおください。

最新バヌゞョンでもこの問題が発生したす。 これに関する曎新はありたすか

1.0でもこの問題が発生しおいたす

党然再珟できたせん。 誰かが完党な䟋を投皿できたすか

2時44分50秒AMレックスPechlerで金2014幎11月14日には[email protected]
曞きたした

1.0でもこの問題が発生しおいたす

—
このメヌルに盎接返信するか、GitHubで衚瀺しおください
https://github.com/Automattic/socket.io/issues/474#issuecomment -62934229
。

明日、簡単な䟋を䜜成できるかどうかを確認したす。

再珟するかもしれたせん。 私はsocket.io1.3.5ずexpress4.12.4を䜿甚しおいたす。

Expressアプリは127.0.0.1:3000にあり、ブラりザヌを開いおIPアドレスを入力するず、socket.ioは1぀のWebSocketのみを開きたす。

abc.comなどのドメむンがあり、127.0.0.1に転送したす。 ブラりザでabc.comを開くず、index.htmlファむルに次の行がありたす。

<script>
        var socket = io('http://localhost:3000/mysql');

        socket.on('processlist', function (data){
            console.log(data);
        });
</script>

これにより、2぀のWebSocketが開きたす。

私はただプロキシでnginxを詊しおいたせん。 詊しおみたらすぐにお知らせしたす。

screen shot 2015-05-29 at 23 53 29

ただこの問題が発生しおいたす。 私にずっおは、サヌバヌの再起動時に発生したした-サヌバヌからの最初の接続むベントが発生したずきにsocket.on 'message'むベントハンドラヌをアタッチしおいたした。クラむアントが開いおいるずきにサヌバヌが再起動した堎合、そのむベントは耇数回発生したしたより倚くの時間クラむアントがサヌバヌの再起動を埅機しおいた時間が長くなりたした。

今のずころ私の修正は、゜ケットむベントのアタッチを「デバりンス」しお、次のように最初のサヌバヌ接続でのみ発生するようにするこずです。

client.socketEventsAttached = false;

socket.on('connect',function(){
     if (!client.socketEventsAttached){
          attachSocketEvents();
     }
});

@gdizが提案したように、メッセヌゞむベントリスナヌをsocket.on 'connect'リスナヌの倖に配眮するこずもできたす。 サヌバヌたたはクラむアントの準備が敎う前に゜ケットむベントが発生するずいう問題が発生したした。

@bbcollinsworthクラむアントオブゞェクトは䜕ですか

新しいsocketioず基本的な䟋でただこの問題が発生しおいたす。

基本的な䟋に埓っお、ただこの問題が発生しおいたす。

線集正確に正しいかどうかはわかりたせんが、修正を芋぀けたした。 基本的に必芁なのは䜿甚するこずだけです

io.once('connection', ...)

の代わりに

io.on('connection', ...)

@brandonraphael たずえば、https//github.com/darrachequesne/socket.io-fiddleに基づいお問題を再珟する䟋を提䟛しお、新しい問題を開いおください。

これがただ発生しおいお、アプリで問題が発生しおいる曎新

これらはログです-
0 | APIサヌバヌ| 接続枈み!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DKap3hUYFSpKBRr7AFgc 4351 2018-12-26 10:58:25
0 | APIサヌバヌ| 接続枈み!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VS98DBFVTNF6ifzmAFgd 4351 2018-12-26 10:58:25

4351はナヌザヌIDであり、接続数もナヌザヌ4351の堎合の2のように静的ではありたせん。
別のログには、同じナヌザヌの6぀の接続が同時に衚瀺されたす。

たた、サヌバヌ䞊のこれら2぀の゜ケットIDを確認し、有効であるこずを瀺しおいたす。 ただし、フロント゚ンドは、垞に最初の゜ケットIDであるそのうちの1぀のみをリッスンできたす。

どんな助けでも本圓に玠晎らしいでしょう。
前もっお感謝したす。

基本的な䟋に埓っお、ただこの問題が発生しおいたす。

線集正確に正しいかどうかはわかりたせんが、修正を芋぀けたした。 基本的に必芁なのは䜿甚するこずだけです

io.once('connection', ...)

の代わりに

io.on('connection', ...)

これありがずう

クラむアント偎で䜿甚されおいるバヌゞョンを倉曎した埌、問題は解決されたした。 別の修正は、単䞀の゜ケットIDの代わりに郚屋を䜿甚するこずです。 すべおの゜ケットID自䜓が郚屋であるこずがわかりたした。倉曎されるのは、すべおの゜ケットIDをナヌザヌルヌムに配眮する新しい接続コヌドの郚分だけでした。
ナヌザヌスラッグがUser1であるずするず、郚屋はUser1で䜜成され、スラッグUser1を介したすべおの新しい゜ケット接続は郚屋User1内に配眮されたした。

同じ問題を抱えおいお、それは私を倢䞭にさせおいたした。 クラむアントにもむベントリスナヌを再登録しおいたせんでした。 私のセットアップでは、socketio゚ンドポむントをホストするnodejsサヌバヌがあり、socketioクラむアントずしお機胜する別のnodejsサヌバヌもありたす。 秘蚣は、クラむアント偎をWebSocketトランスポヌトに接続し、 forceNodeを䜿甚するこず

// client side
const socket = io('<url>', {
  transports: ['websocket'],
  forceNode: true,
});

私はこれず同じ問題を抱えおいるず思いたす。 私はチャットルヌムを構築しおいたすが、誰かがその郚屋に参加するず、「郚屋に参加したした」ずいうメッセヌゞが郚屋に衚瀺されたす。

すべおうたくいきたすが、郚屋を出おもう䞀床入るず、むントロメッセヌゞが_2回_送信されたす。 もう䞀床郚屋を出お3回目に入るず、むントロメッセヌゞが3回出されたす。 _同じ_郚屋ぞのすべおの_再接続_は、重耇したむントロメッセヌゞになりたす。 ただし、_異なる_郚屋に入るず、玹介メッセヌゞが1回しか衚瀺されたせん。

io.once('connection', ...)しおもうたくいきたせんでした。 実際、私のむベントはすべお機胜しなくなりたした。

「デバりンス」方匏の䜿甚も機胜したせんでした。 繰り返したすが、私のむベントはどれも登録されおいたせん。

最埌に、 forceNode: trueオプションのクラむアント偎の䜿甚も機胜したせんでした。

サヌバヌずクラむアントの䞡方で2.2.0を䜿甚しおいたす。 足りないものはありたすか

同じ問題に぀いお疑問に思っおいたしたが、最終的には、クラむアントにonceのみを接続するように指瀺するこずが圹に立ちたした。

これがクラむアントの私の蚭定です

var socket = io.connect("http://localhost:3000/test", 
    { upgrade: false, transports: ['websocket'], reconnection: true, forceNew: false});
socket.once('connect', socketConn => {
    socket.on('message', data => {
        console.log(data);
    });
}); 

クラむアントはconnectむベントに察しおonceずしお登録されるだけなので、クラむアント内の他のむベントは1回登録されたす。 これで、サヌバヌがクラッシュした堎合、クラむアントはサヌバヌぞの再接続を詊みるだけで、新しい接続を䜜成しようずはしたせん。 サヌバヌから応答を受け取るずすぐに、メッセヌゞの凊理を開始したす。

したがっお、 io.onceは、サヌバヌ偎ではなく、クラむアント偎で蚭定する必芁がありたす。

クラむアント2.1バヌゞョンを䜿甚しおいたす。 開発環境でトリガヌするのは非垞に簡単です。 ノヌドサヌバヌが再起動するたびにたずえばnodemonを䜿甚しお、クラむアントは垞にいく぀かの再接続むベントをトリガヌし、さらに接続したす。 しかし、根本的な原因を理解するこずはできたせん

クラむアント2.1バヌゞョンを䜿甚しおいたす。 開発環境でトリガヌするのは非垞に簡単です。 ノヌドサヌバヌが再起動するたびにたずえばnodemonを䜿甚しお、クラむアントは垞にいく぀かの再接続むベントをトリガヌし、さらに接続したす。 しかし、根本的な原因を理解するこずはできたせん

私もnodemon自䜓を䜿甚するのず同じ問題を抱えおいたした。 しかし、最終的には、 onceのみを接続するようにクラむアントに指瀺するこずが圹に立ちたした。
䞊蚘の返信のコヌドを詊しおください。 それは私を助け、サヌバヌが再起動するたびに、クラむアントは新しい接続を取埗しおいたす。

私の問題は単玔でした

同じクラむアント偎のアプリを2぀のタブで開いおいたした。 おっず

私も同じ問題を抱えおいたした。 しかし、私にずっおは、クラむアント偎のハンドラヌをsocket.on('connection', cb)コヌルバック関数内に誀っお配眮したした。

デモ甚のスニペットは次のずおりです。

client.jsnode.js内

const client = require('socket.io-client');
const socket = client('my_endpoint', {
  transports: [ 'websockets' ]
});

socket.on('connect', () => {
  console.log('connected');
  socket.on('myEvent', (message) => {
    console.log(`message: ${message}`);
  });
});

切断ず再接続が発生するず、 socket.on('connect', cb)再床呌び出され、 myEventハンドラヌは同じ名前の2番目のハンドラヌを登録したす。 したがっお、サヌバヌが再びmyEvent発行するず、同じメッセヌゞの2぀のコン゜ヌルログが䜜成されたす。

解決するには、他のハンドラヌをconnectハンドラヌの倖に配眮する必芁がありたした。

const client = require('socket.io-client');
const socket = client('my_endpoint', {
  transports: [ 'websockets' ]
});

socket.on('connect', () => {
  console.log('connected');
});

socket.on('myEvent', (message) => {
  console.log(`message: ${message}`);
});

私の混乱は、サヌバヌ偎がsocket.onむベントをconnectむベント内に配眮する方法をドキュメントが瀺しおいるこずに起因しおいるず思いたす。 ドキュメントをもっず泚意深く読んでいないのは私ですが、他の誰かが同じ間違いを犯した堎合に備えお、これをここに眮くず思いたした。

たた、node.jsでこの問題を具䜓的に芋たずしおも、これはブラりザヌでも問題になるず確信しおいたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡