Socket.io: カスタム名前空間を使用する場合、Middleware(.use)は接続を発行しません

作成日 2017年10月11日  ·  12コメント  ·  ソース: socketio/socket.io

あなたはしたい:

  • [x]バグを報告する
  • []機能をリクエストする

現在の動作

ミドルウェアでカスタム名前空間を使用すると、サーバーは「接続」イベントを受け取りますが、クライアントは「接続」イベントを受け取りません。

これは機能します:

io.use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

これは動作しません:

// Following works, but client does not receive 'connect' or 'connection':
io.of('/admin').use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

サイトノート

また、非常に奇妙です。次のコードを実行すると、/ adminのミドルウェアが実行されていなくても、default-namespaceは「connect」イベントを発行しません。

io.on('connection', socket => {
  console.log('client connected');
});

io.of('/admin').use((socket, next) => {
   console.log('middleware running...');
   next();
}).on('connection', socket => {
  console.log('client connected');
});

これを修正するに.use((socket, next) => { next(); }) 、デフォルトの名前空間に

再現手順(現在の動作がバグの場合)

上記をご覧ください

期待される動作

接続時に、クライアントは「接続」を受信する必要があります

セットアップ

  • OS:macOS Sierra 10.12.6
  • ブラウザ:Chrome
  • ノード:v8.2.1
  • NPM:5.4.2
  • socket.ioバージョン:2.0.3
bug

最も参考になるコメント

@JanisRubens詳細なレポートをありがとう:+ 1 :、私は最終的に再現することができました。 https://github.com/socketio/socket.io/pull/3197で修正

全てのコメント12件

こんにちは! クライアントをどのように初期化していますか? 以下は私のために働くようです:

io.use((socket, next) => {
   console.log('(default) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(default) client connected');
});

// Following works, but client does not receive 'connect' or 'connection':
io.of('/admin').use((socket, next) => {
   console.log('(admin) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(admin) client connected');
});

// client
const socket = require('socket.io-client')('http://localhost:3000/admin');

socket.on('connect', onConnect);

function onConnect(){
  console.log('connect ' + socket.id);
}

出力(フィドル):

server listening on port 3000
(default) middleware running...
(default) client connected
(admin) middleware running...
(admin) client connected

いいえ、それは私のために働いていません。 完全なコード、実例:

サーバ:

let express = require('express'),
    app = new express(),
    server = app.listen(3005, 'localhost'),
    io = require('socket.io')(server)
;

io.on('connection', socket => {
  console.log('client connected');
});

io.of('/admin')
  .use((socket, next) => {
    console.log('middleware running...');
    next();
  })
  .on('connection', socket => {
    console.log('admin connected');
  })
;

クライアント:

$(function () {
    let socket;

    $('#btn-connect').click(() => {
        console.log('Connecting ...');

        socket = io('http://localhost:3005');

        socket.on('connect', () => {
            console.log(`Connected to ${url} with id: ${socket.id}`);
        });

        socket.on('disconnect', reason => {
            console.log(`Disconnected. Reason: ${reason}`);
        });
    });

    $('#btn-connect-admin').click(() => {
        console.log('Connecting to admin ...');

        socket = io('http://localhost:3005/admin');

        socket.on('connect', () => {
            console.log(`Connected to ${url} with id: ${socket.id}`);
        });

        socket.on('disconnect', reason => {
            console.log(`Disconnected. Reason: ${reason}`);
        });
    });
});

ミドルウェアを削除すると、両方に接続できます。 ミドルウェアを管理者のみに追加すると、デフォルトの名前空間でも/ adminでも接続イベントが発生しません。

サーバーはすべてを正しく表示します。

  • クライアント接続
  • ミドルウェアの実行中...
  • 管理者が接続しました

何も? :(

@MickLこれに関する更新はありますか?
同じ問題に遭遇しました。
これを見つけたかどうかはわかりません。 唯一の接続の問題はルート名前空間にあり、ルートパスにもミドルウェアを追加すると、ミドルウェアもそれに接続できるようになります。 (これは簡単な修正tbhになる可能性があります)

それは次のシナリオに帰着します:

If namespace A('/)' and B('/otherPath') has no middleware it connects to both fine;
If namespace A has no middleware and B has. It connects to A on server side, but client sides 'connect' event listener never gets called, B namespace connects fine;
If namespace A and B both has middleware it can connect to both;

いいえ、回避策を使用しました。 の代わりに:

io.of('/admin')
  .use((socket, next) => {
    if(tokenValid()) {
       next();
    } else {
      next(new Error('Authentication error'));
    }
  })
  .on('connection', socket => {
    console.log('admin connected');
  })
;

私が書いた:

io.of('/admin')
  .on('connection', socket => {
    if(!tokenValid()) {
       socket.disconnect();
    }

    console.log('admin connected');
  })
;

これに多くの時間を費やしましたが、クライアントはサーバーに接続しているようですが、クライアントは接続イベントを取得していません。

私はこれがうまくいくと思います。 しかし、ミドルウェアを本来の用途に適切に使用できないのは残念です。

@darrachequesne提供してテストした例は、報告された問題によるものではありません。

デフォルトの名前空間からミドルウェアを削除してから、接続を試みる必要があります。

このような:

io.on('connection', socket => {
  console.log('(default) client connected');
});

io.of('/admin').use((socket, next) => {
   console.log('(admin) middleware running...');
   next();
}).on('connection', socket => {
  console.log('(admin) client connected');
});

// client
const socket = require('socket.io-client')('http://localhost:3000/');
const socket_two = require('socket.io-client')('http://localhost:3000/admin');
//wont trigger
socket.on('connect', onConnect);
//will trigger
socket_two.on('connect', onConnect);

function onConnect(){
  console.log('connect ' + socket.id);
}

今では失敗するはずです。
上記で動作する/動作しない場合を参照してください。

乾杯。

@JanisRubens詳細なレポートをありがとう:+ 1 :、私は最終的に再現することができました。 https://github.com/socketio/socket.io/pull/3197で修正

私はまだこれに直面しています!
名前空間クライアント受信イベントを作成する前ですが、名前空間を追加してミドルウェアを使用した後、クライアントはイベントを受信して​​いませんが、フレームはクロムに表示されていました。

+1

@adeelhussain @ElioTohmどのバージョンを使用していますか? フィドルでケースを再現できますか?

socketiov2.1.1およびsocket.io-redisv5.2.0を使用する
早急にフィドルで再現してみます

このページは役に立ちましたか?
0 / 5 - 0 評価