Socket.io: L'intergiciel (.use) n'émet pas de connexion lors de l'utilisation d'un espace de noms personnalisé

Créé le 11 oct. 2017  ·  12Commentaires  ·  Source: socketio/socket.io

Tu veux:

  • [x] signaler un bogue
  • [] demander une fonctionnalité

Comportement actuel

Lors de l'utilisation d'un espace de noms personnalisé avec un middleware, le serveur obtient un événement 'connection', mais le client ne reçoit pas d'événement 'connect'.

Cela marche:

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

Cela ne fonctionne pas:

// 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

Également très étrange: si je fais le code suivant, l'espace de noms par défaut n'émet pas non plus d'événement 'connect' même si le middleware de / admin n'est pas en cours d'exécution.

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

Pour résoudre ce problème, je dois ajouter .use((socket, next) => { next(); }) à l'espace de noms par défaut. Mais toujours / admin n'émet pas de «connexion».

Etapes à reproduire (si le comportement actuel est un bug)

S'il vous plaît voir ci-dessus

Comportement attendu

Lors de la connexion, le client devrait recevoir «se connecter»

Installer

  • Système d'exploitation: macOS Sierra 10.12.6
  • navigateur: Chrome
  • Nœud: v8.2.1
  • NPM: 5.4.2
  • Version de socket.io: 2.0.3
bug

Commentaire le plus utile

@JanisRubens Merci pour le rapport détaillé: +1 https://github.com/socketio/socket.io/pull/3197

Tous les 12 commentaires

Salut! Comment initialisez-vous le client? Ce qui suit semble fonctionner pour moi:

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

Sortie ( violon ):

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

Non, cela ne fonctionne pas pour moi. Code complet, exemple fonctionnel:

Serveur:

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

Client:

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

Si je supprime le middleware, je peux me connecter aux deux. Si j'ajoute le middleware à l'administrateur uniquement, je n'obtiens aucun événement de connexion sur l'espace de noms par défaut ni / admin.

Le serveur montre tout correctement:

  • client connecté
  • middleware en cours d'exécution ...
  • admin connecté

Rien? :(

@MickL Des mises à jour à ce sujet?
Ran dans le même problème aussi.
Je ne sais pas si vous l'avez repéré. Le seul problème de connexion concerne l'espace de noms racine et si vous ajoutez également un middleware pour le chemin racine, il pourra également s'y connecter. (cela peut être une solution miracle)

Cela se résume aux scénarios suivants:

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;

Non, j'ai utilisé une solution de contournement. Au lieu de:

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

J'ai écrit:

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

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

J'ai beaucoup dépensé pour cela et il semble que le client se connecte au serveur mais que le client n'obtient pas l'événement de connexion.

Je suppose que cela peut fonctionner. Mais c'est dommage que nous ne puissions pas utiliser correctement le middleware pour son utilisation prévue.

@darrachequesne L'exemple que vous avez fourni et testé ne correspond pas au problème signalé.

Vous devez supprimer le middleware de l'espace de noms par défaut, puis essayer de vous connecter.

Comme ça:

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

Maintenant, cela devrait échouer.
Voir les cas où cela fonctionne / ne fonctionne pas ci-dessus.

À votre santé.

@JanisRubens Merci pour le rapport détaillé: +1 https://github.com/socketio/socket.io/pull/3197

Je suis toujours confronté à ça!
Avant de créer un espace de noms, le client reçoit des événements, mais après l'ajout d'un espace de noms et l'utilisation du middleware, le client ne reçoit aucun événement, mais les cadres s'affichent sur le chrome.

+1

@adeelhussain @ElioTohm quelle version utilisez-vous? Êtes-vous capable de reproduire le cas avec le violon ?

en utilisant socketio v2.1.1 et socket.io-redis v5.2.0
j'essaierai de le reproduire avec du violon dès que possible

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

jloa picture jloa  ·  4Commentaires

doughsay picture doughsay  ·  4Commentaires

karmac2015 picture karmac2015  ·  3Commentaires

varHarrie picture varHarrie  ·  3Commentaires

dmuth picture dmuth  ·  3Commentaires