Express 中间件未捕获 socket.io 的请求事件
Express middleware not capturing request events for socket.io
我正在使用 Express (v4.17.3)、Socket.io 和 Node.Js 的http 模块。我正在为 express 添加一个中间件来捕获所有传入的请求,但是失败了。
我将首先展示我正在使用的代码和输出,然后解释我的 understanding/expectation 输出(我是 Node 和所有提到的库的新手,所以我可能遗漏了一些东西)
首先,下面是我所指的代码。使用 Express 的中间件,我试图捕获所有传入的请求并记录它们,并对 http on("request")
执行相同的操作。但是,发送到 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`)
})
GET /
时的输出
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...
我的预期输出是中间件 app.use()
和 on("request")
(“Express request =”&“Http request =”)
的日志相等
我的理解:
1- 当我在下面的代码中为 express 添加一个中间件时,任何传入的请求都应该先在这里捕获,然后再去其他地方。 (正确吗?)
app.use((req,res,next)=>{...})
2- 当我将 express 应用程序 作为参数传递给 http 的 createServer
时,express 应用程序将被视为侦听器,任何 request
事件都将传递给它。 (正确吗?)
const server = require('http').createServer(app);
所以如果我的理解是正确的,为什么请求事件捕获的所有请求都没有传递给中间件?
我认为您需要记录套接字上发送的消息。
io.on('connection', (socket) => { socket.on('chat message', (msg) => { console.log('message: ' + msg); }); });
这是正常的。 Socket.io 将自己置于 express(或 http 服务器上传入请求的任何其他侦听器)前面,以便它在 Express 看到请求之前接受请求。因此,Express(或其中间件)永远不会看到任何 socket.io 连接请求。
Socket.io 有它的 own middleware layer,您可以使用它来参与 socket.io 请求的初始化。
或者,您可以使用 io.on('connection', ...)
事件处理程序注册传入的 socket.io 连接(在它们已经连接后调用)。
When I add a middleware for express as in the code below, any incoming requests should be captured here first before going anywhere else. (correct?)
除了直接在 http 服务器上注册请求处理程序并将自身插入侦听器链中的 Express 之前的代码之外,这是正确的,从而防止 Express 看到任何发往 socket.io 的请求。
When I'm passing the express app as an argument to http'screateServer, that the express app will be treated as a listener and any request events will be passed to it. (correct?)
没错。但是 socket.io 跳到 Express 和 takes/hides 任何它想要的请求前面,这样 Express 永远不会看到它们。
如果你很好奇,这里是 socket.io code 跳到 http 服务器所有侦听器前面从而绕过 express 侦听器的
:
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);
}
}
});
}
它将所有现有的侦听器抓取到一个数组中。然后,它将它们全部删除。然后,它注册 request
事件本身,如果它是 socket.io 请求,则它不会调用先前的侦听器。如果它不是 socket.io 前缀,那么它会手动调用先前的侦听器。
我正在使用 Express (v4.17.3)、Socket.io 和 Node.Js 的http 模块。我正在为 express 添加一个中间件来捕获所有传入的请求,但是失败了。
我将首先展示我正在使用的代码和输出,然后解释我的 understanding/expectation 输出(我是 Node 和所有提到的库的新手,所以我可能遗漏了一些东西)
首先,下面是我所指的代码。使用 Express 的中间件,我试图捕获所有传入的请求并记录它们,并对 http on("request")
执行相同的操作。但是,发送到 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`)
})
GET /
时的输出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...
我的预期输出是中间件 app.use()
和 on("request")
(“Express request =”&“Http request =”)
我的理解:
1- 当我在下面的代码中为 express 添加一个中间件时,任何传入的请求都应该先在这里捕获,然后再去其他地方。 (正确吗?)
app.use((req,res,next)=>{...})
2- 当我将 express 应用程序 作为参数传递给 http 的 createServer
时,express 应用程序将被视为侦听器,任何 request
事件都将传递给它。 (正确吗?)
const server = require('http').createServer(app);
所以如果我的理解是正确的,为什么请求事件捕获的所有请求都没有传递给中间件?
我认为您需要记录套接字上发送的消息。
io.on('connection', (socket) => { socket.on('chat message', (msg) => { console.log('message: ' + msg); }); });
这是正常的。 Socket.io 将自己置于 express(或 http 服务器上传入请求的任何其他侦听器)前面,以便它在 Express 看到请求之前接受请求。因此,Express(或其中间件)永远不会看到任何 socket.io 连接请求。
Socket.io 有它的 own middleware layer,您可以使用它来参与 socket.io 请求的初始化。
或者,您可以使用 io.on('connection', ...)
事件处理程序注册传入的 socket.io 连接(在它们已经连接后调用)。
When I add a middleware for express as in the code below, any incoming requests should be captured here first before going anywhere else. (correct?)
除了直接在 http 服务器上注册请求处理程序并将自身插入侦听器链中的 Express 之前的代码之外,这是正确的,从而防止 Express 看到任何发往 socket.io 的请求。
When I'm passing the express app as an argument to http'screateServer, that the express app will be treated as a listener and any request events will be passed to it. (correct?)
没错。但是 socket.io 跳到 Express 和 takes/hides 任何它想要的请求前面,这样 Express 永远不会看到它们。
如果你很好奇,这里是 socket.io code 跳到 http 服务器所有侦听器前面从而绕过 express 侦听器的
: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);
}
}
});
}
它将所有现有的侦听器抓取到一个数组中。然后,它将它们全部删除。然后,它注册 request
事件本身,如果它是 socket.io 请求,则它不会调用先前的侦听器。如果它不是 socket.io 前缀,那么它会手动调用先前的侦听器。