Cuando se usa un espacio de nombres personalizado con un middleware, el servidor obtiene un evento de "conexión", pero el cliente no recibe el evento de "conexión".
Esto funciona:
io.use((socket, next) => {
console.log('middleware running...');
next();
}).on('connection', socket => {
console.log('client connected');
});
Esto no funciona:
// 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');
});
También es muy extraño: si hago el siguiente código, el espacio de nombres predeterminado no emite ningún evento de 'conexión', incluso aunque el middleware de / admin no se esté ejecutando.
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');
});
Para solucionar este problema, tengo que agregar .use((socket, next) => { next(); })
al espacio de nombres predeterminado. Pero aún / admin no emite 'conectar'.
Por favor ver arriba
Al conectarse, el cliente debe recibir 'conectar'
¡Hola! ¿Cómo está inicializando el cliente? Lo siguiente parece funcionar para mí:
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);
}
Salida ( violín ):
server listening on port 3000
(default) middleware running...
(default) client connected
(admin) middleware running...
(admin) client connected
No, no me está funcionando. Código completo, ejemplo de trabajo:
Servidor:
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');
})
;
Cliente:
$(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 elimino el middleware, puedo conectarme a ambos. Si agrego el middleware solo al administrador, no obtengo ningún evento de conexión en el espacio de nombres predeterminado ni / admin.
El servidor muestra todo correctamente:
¿Nada? :(
@MickL ¿ Alguna actualización sobre esto?
También encontré el mismo problema.
No estoy seguro de haber visto esto. El único problema de conexión es con el espacio de nombres raíz y si agrega un middleware también para la ruta raíz, también podrá conectarse a él. (esto puede ser una solución rápida tbh)
Se reduce a los siguientes escenarios:
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;
No, utilicé una solución alternativa. En vez de:
io.of('/admin')
.use((socket, next) => {
if(tokenValid()) {
next();
} else {
next(new Error('Authentication error'));
}
})
.on('connection', socket => {
console.log('admin connected');
})
;
Escribí:
io.of('/admin')
.on('connection', socket => {
if(!tokenValid()) {
socket.disconnect();
}
console.log('admin connected');
})
;
Gasté mucho en esto y parece que el cliente se conecta al servidor, pero el cliente no obtiene el evento de conexión.
Supongo que esto puede funcionar. Pero es una pena que no podamos utilizar el middleware correctamente para el uso previsto.
@darrachequesne El ejemplo que proporcionó y en el que probó no corresponde al problema informado.
Debe eliminar el middleware del espacio de nombres predeterminado y luego intentar conectarse.
Me gusta esto:
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);
}
Ahora debería fallar.
Vea los casos en los que funciona / no funciona arriba.
Salud.
@JanisRubens Gracias por el informe detallado: +1:, finalmente pude reproducirlo. Corregido por https://github.com/socketio/socket.io/pull/3197
¡Todavía estoy enfrentando esto!
Antes de crear el espacio de nombres, el cliente recibe eventos, pero después de agregar el espacio de nombres y usar middleware, el cliente no recibe ningún evento, pero los marcos se muestran en Chrome.
+1
@adeelhussain @ElioTohm ¿ qué versión estás usando? ¿Eres capaz de reproducir el caso con el violín ?
usando socketio v2.1.1 y socket.io-redis v5.2.0
Intentaré reproducirlo con violín lo antes posible
Comentario más útil
@JanisRubens Gracias por el informe detallado: +1:, finalmente pude reproducirlo. Corregido por https://github.com/socketio/socket.io/pull/3197