Socket.io: Middleware (.use) tidak memancarkan koneksi saat menggunakan namespace kustom

Dibuat pada 11 Okt 2017  ·  12Komentar  ·  Sumber: socketio/socket.io

Yang kamu ingin:

  • [x] laporkan bug
  • [] minta fitur

Perilaku saat ini

Saat menggunakan namespace kustom dengan middleware, server mendapatkan peristiwa 'koneksi', tetapi klien tidak menerima peristiwa 'menghubungkan'.

Ini bekerja:

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

Ini tidak bekerja:

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

Sitenote

Juga sangat aneh: Jika saya melakukan kode berikut, maka namespace default juga tidak memancarkan acara 'terhubung' meskipun middleware dari / admin tidak berjalan.

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

Untuk memperbaikinya saya harus menambahkan .use((socket, next) => { next(); }) ke namespace default. Tapi tetap / admin tidak memancarkan 'terhubung'.

Langkah-langkah untuk mereproduksi (jika perilaku saat ini adalah bug)

Silakan lihat di atas

Perilaku yang diharapkan

Saat koneksi, klien harus menerima 'terhubung'

Mendirikan

  • OS: macOS Sierra 10.12.6
  • browser: Chrome
  • Node: v8.2.1
  • NPM: 5.4.2
  • versi socket.io: 2.0.3
bug

Komentar yang paling membantu

@JanisRubens Terima kasih atas laporan terperinci: +1 https://github.com/socketio/socket.io/pull/3197

Semua 12 komentar

Hai! Bagaimana Anda menginisialisasi klien? Berikut ini tampaknya berhasil untuk saya:

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

Output ( biola ):

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

Tidak, itu tidak berhasil untuk saya. Kode lengkap, contoh kerja:

Server:

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

Klien:

$(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}`);
        });
    });
});

Jika saya menghapus middleware, saya dapat terhubung ke keduanya. Jika saya menambahkan middleware ke admin saja, saya tidak mendapatkan event koneksi di namespace default atau / admin.

Server menunjukkan semuanya dengan benar:

  • klien terhubung
  • middleware berjalan ...
  • admin terhubung

Tidak ada? :(

@MickL Ada pembaruan tentang ini?
Mengalami masalah yang sama juga.
Tidak yakin apakah Anda melihat ini. Satu-satunya masalah koneksi adalah dengan ruang nama root dan jika Anda menambahkan middleware juga untuk jalur root, itu juga akan dapat terhubung ke sana. (ini bisa menjadi perbaikan cepat tbh)

Itu tergantung pada skenario berikut:

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;

Tidak, saya menggunakan solusi. Dari pada:

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

Saya menulis:

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

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

Saya menghabiskan banyak uang untuk ini dan sepertinya klien terhubung ke server tetapi klien tidak mendapatkan acara koneksi.

Saya kira ini bisa berhasil. Namun sayang sekali kami tidak dapat menggunakan middleware dengan benar untuk tujuan penggunaannya.

@darrachequesne Contoh yang Anda berikan dan uji tidak sesuai dengan masalah yang dilaporkan.

Anda perlu menghapus middleware dari namespace default dan kemudian mencoba menghubungkan.

Seperti ini:

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

Sekarang seharusnya gagal.
Lihat kasus ketika berhasil / tidak berfungsi di atas.

Bersulang.

@JanisRubens Terima kasih atas laporan terperinci: +1 https://github.com/socketio/socket.io/pull/3197

Saya masih menghadapi ini!
Sebelum membuat namespace, klien menerima peristiwa, tetapi setelah menambahkan namespace dan menggunakan middleware, klien tidak menerima peristiwa apa pun, namun bingkainya ditampilkan di chrome.

+1

@adeelhussain @ElioTohm versi mana yang Anda gunakan? Apakah Anda dapat mereproduksi casing dengan biola ?

menggunakan socketio v2.1.1 dan socket.io-redis v5.2.0
Saya akan mencoba mereproduksinya dengan biola secepatnya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat