Socket.io: Middleware (.use) gibt bei Verwendung eines benutzerdefinierten Namespace keine Verbindung aus

Erstellt am 11. Okt. 2017  ·  12Kommentare  ·  Quelle: socketio/socket.io

Du möchtest:

  • [x] einen Fehler melden
  • [] fordere eine Funktion an

Aktuelles Verhalten

Wenn Sie einen benutzerdefinierten Namespace mit einer Middleware verwenden, erhält der Server ein Verbindungsereignis, der Client erhält jedoch kein Verbindungsereignis.

Das funktioniert:

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

Das funktioniert nicht:

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

Sitenotes

Ebenfalls sehr seltsam: Wenn ich den folgenden Code mache, gibt auch der Standard-Namespace kein 'Connect'-Ereignis aus, obwohl die Middleware von / admin nicht ausgeführt wird.

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

Um dies zu beheben, muss ich .use((socket, next) => { next(); }) zum Standard-Namespace hinzufügen. Trotzdem gibt / admin keine 'Verbindung' aus.

Schritte zum Reproduzieren (wenn das aktuelle Verhalten ein Fehler ist)

Bitte siehe oben

Erwartetes Verhalten

Bei der Verbindung sollte der Client "Verbinden" erhalten.

Konfiguration

  • Betriebssystem: macOS Sierra 10.12.6
  • Browser: Chrome
  • Knoten: v8.2.1
  • NPM: 5.4.2
  • socket.io version: 2.0.3
bug

Hilfreichster Kommentar

@ JanisRubens Danke für den ausführlichen Bericht: +1 :, konnte ich schließlich reproduzieren. Behoben durch https://github.com/socketio/socket.io/pull/3197

Alle 12 Kommentare

Hallo! Wie initialisieren Sie den Client? Folgendes scheint für mich zu funktionieren:

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

Ausgabe ( Geige ):

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

Nein, es funktioniert nicht bei mir. Vollständiger Code, Arbeitsbeispiel:

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

Klient:

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

Wenn ich die Middleware entferne, kann ich mich mit beiden verbinden. Wenn ich die Middleware nur dem Administrator hinzufüge, erhalte ich weder ein Verbindungsereignis im Standard-Namespace noch / admin.

Server zeigt alles richtig:

  • Client verbunden
  • Middleware läuft ...
  • admin verbunden

Nichts? :(

@ MickL Irgendwelche Updates dazu?
Bin auch auf das gleiche Problem gestoßen.
Ich bin mir nicht sicher, ob du das entdeckt hast. Das einzige Verbindungsproblem besteht im Root-Namespace. Wenn Sie eine Middleware auch für den Root-Pfad hinzufügen, kann diese ebenfalls eine Verbindung herstellen. (Dies kann eine schnelle Lösung sein, tbh)

Es kommt auf folgende Szenarien an:

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;

Nein, ich habe eine Problemumgehung verwendet. Anstatt von:

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

Ich schrieb:

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

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

Ich habe viel dafür ausgegeben und es scheint, dass der Client eine Verbindung zum Server herstellt, der Client jedoch das Verbindungsereignis nicht erhält.

Ich denke das kann funktionieren. Aber es ist eine Schande, dass wir Middleware nicht richtig für den beabsichtigten Gebrauch verwenden können.

@darrachequesne Das Beispiel, das Sie bereitgestellt und getestet haben, entspricht nicht dem gemeldeten Problem.

Sie müssen die Middleware aus dem Standard-Namespace entfernen und dann versuchen, eine Verbindung herzustellen.

So was:

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

Jetzt sollte es scheitern.
Sehen Sie sich die Fälle an, in denen es oben funktioniert / nicht funktioniert.

Prost.

@ JanisRubens Danke für den ausführlichen Bericht: +1 :, konnte ich schließlich reproduzieren. Behoben durch https://github.com/socketio/socket.io/pull/3197

Ich stehe immer noch davor!
Vor dem Erstellen eines Namespace-Clients erhalten Sie Ereignisse, aber nach dem Hinzufügen eines Namespace und der Verwendung von Middleware empfängt der Client kein Ereignis, jedoch wurden die Frames auf dem Chrome angezeigt.

+1

@adeelhussain @ElioTohm Welche Version verwendest du? Können Sie den Fall mit der Geige reproduzieren?

Verwenden von socketio v2.1.1 und socket.io-redis v5.2.0
Ich werde versuchen, es so schnell wie möglich mit Geige zu reproduzieren

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen