Estoy usando Express (v4.17.3), Socket.io y el módulo http de Node.Js. Estoy agregando un middleware para express para capturar todas las solicitudes entrantes, pero está fallando.
Primero mostraré el código que estoy usando y la salida, luego explicaré mi comprensión/expectativa de la salida (soy nuevo en Node y en todas las bibliotecas mencionadas, así que tal vez me esté perdiendo algo)
En primer lugar, a continuación se muestra el código al que me refiero. Usando el middleware de Express , intento capturar todas las solicitudes entrantes y registrarlas, y hago lo mismo para http on("request") . Sin embargo, el middleware no captura las solicitudes que van a socket.io .
// Express const express = require("express"); const app = express() // Socket const server = require('http').createServer(app); const {Server} = require("socket.io"); const io = new Server(server) // Want to listen to all incoming requests using the middleware (this doesn't work) app.use((req,res,next)=>{ console.log(`Express request = ${req.url}`) next() }) // Listening to all incoming requests (this works) server.on("request", (req, res)=>{ console.log(`Http request = ${req.url}`) }) server.listen(8080, () => { console.log(`Listening on port 8080`) })salida cuando OBTENGO /
Express request = / Http request = / Http request = /socket.io/socket.io.js Http request = /socket.io/?EIO=4&transport=polling&t=O0va... Http request = /socket.io/?EIO=4&transport=polling&t=O0va24A&sid=c... Http request = /socket.io/?EIO=4&transport=polling&t=O0va24F&sid=c... Http request = /socket.io/?EIO=4&transport=polling&t=O0va27x&sid=c... Mi salida esperada es tener registros iguales para el middleware app.use() y on("request") ("Express request = " & "Http request = ")
Mi entendimiento:
1- Cuando agrego un middleware para express como en el código a continuación, cualquier solicitud entrante debe capturarse aquí primero antes de ir a cualquier otro lugar. (¿correcto?)
app.use((req,res,next)=>{...})
2- Cuando estoy pasando la aplicación express como un argumento para createServer de http, la aplicación express será tratada como un oyente y cualquier evento de request se le pasará. (¿correcto?)
const server = require('http').createServer(app);
Entonces, si mi entendimiento es correcto, ¿por qué todas las solicitudes capturadas por el evento de solicitud no se pasan también al middleware?
Esto es normal. Socket.io se coloca frente a express (o cualquier otro oyente de solicitudes entrantes en el servidor http) para que tome la solicitud antes de que Express la vea. Por lo tanto, Express (o su middleware) nunca ve ninguna solicitud de conexión de socket.io.
Socket.io tiene su propia capa de middleware que puede usar para participar en la inicialización de las solicitudes de socket.io.
O bien, puede registrarse para las conexiones socket.io entrantes (que se llamarán después de que ya estén conectadas) con el io.on('connection', ...) .
Cuando agrego un middleware para express como en el código a continuación, cualquier solicitud entrante debe capturarse aquí primero antes de ir a cualquier otro lugar. (¿correcto?)
Eso es cierto, excepto para el código que registra directamente los controladores de solicitudes directamente en el servidor http y se inserta antes de Express en la cadena de escucha, lo que evita que Express vea las solicitudes destinadas a socket.io.
Cuando paso la aplicación express como argumento a http'screateServer, la aplicación express se tratará como un oyente y se le pasará cualquier evento de solicitud. (¿correcto?)
Eso es verdad. Pero socket.io salta frente a Express y toma/oculta las solicitudes que desea para que Express nunca las vea.
Si tiene curiosidad, aquí está el código socket.io que salta en línea al frente de todos los oyentes para el servidor http, evitando así el oyente expreso:
attachServe(srv) { debug("attaching client serving req handler"); const evs = srv.listeners("request").slice(0); srv.removeAllListeners("request"); srv.on("request", (req, res) => { if (this.clientPathRegex.test(req.url)) { this.serve(req, res); } else { for (let i = 0; i < evs.length; i++) { evs[i].call(srv, req, res); } } }); } Agarra todos los oyentes existentes en una matriz. Luego, los elimina a todos. Luego, se registra para el evento de request en sí mismo y, si es una solicitud de socket.io, entonces no llama a los oyentes anteriores. Si no es un prefijo socket.io, llama manualmente a los oyentes anteriores.
Creo que necesita registrar los mensajes enviados en el socket.
io.on('connection', (socket) => { socket.on('chat message', (msg) => { console.log('message: ' + msg); }); });