首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >表示中间件不捕获socket.io的请求事件

表示中间件不捕获socket.io的请求事件
EN

Stack Overflow用户
提问于 2022-04-17 22:33:58
回答 2查看 158关注 0票数 0

我使用的是Express (v4.17.3)、Socket.io和Node.js的http模块。我正在为express添加一个中间件来捕获所有传入请求,但这是失败的。

我将首先展示我使用的代码和输出,然后解释我对输出的理解/期望(我对Node和所有提到的库都是新手,所以我可能遗漏了什么)

首先,下面是我指的代码。使用Express的中间件,我试图捕获所有传入的请求并记录它们,并对http on("request")进行同样的记录。然而,发送到socket.io的请求不会被中间件捕获。

代码语言:javascript
运行
复制
// 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`)
})

当我得到/得到时输出

代码语言:javascript
运行
复制
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请求=“& "Http请求")

我的理解:

1-当我为express添加中间件时(如下面的代码所示),任何传入的请求都应该先在这里捕获,然后再进入其他任何地方。(对吗?)

app.use((req,res,next)=>{...})

2-当我将快递应用程序作为参数传递给http的createServer时,快递应用程序将被视为侦听器,任何request事件都将传递给它。(对吗?)

const server = require('http').createServer(app);

因此,如果我的理解是正确的,为什么请求事件捕获的所有请求也不传递给中间件?

EN

Stack Overflow用户

回答已采纳

发布于 2022-04-17 22:53:45

这很正常。Socket.io将自己置于express (或http服务器上任何其他传入请求的侦听器)前面,以便在Express看到请求之前接受它。因此,Express (或它的中间件)从未看到任何socket.io连接请求。

Socket.io有它的自己的中间件层,您可以使用它来参与socket.io请求的初始化。

或者,您可以向socket.io事件处理程序注册传入的io.on('connection', ...)连接(在它们已经连接之后将被调用)。

当我为express添加中间件时,如下面的代码所示,任何传入的请求都应该先在这里捕获,然后再进入其他任何地方。(对吗?)

除了直接在http服务器上注册请求处理程序并在侦听器链中的Express之前插入自身的代码之外,这是正确的,从而防止Express看到任何指向socket.io的请求。

当我将express应用程序作为参数传递给http‘’screateServer时,它将被视为侦听器,任何请求事件都将传递给它。(对吗?)

那是真的。但是socket.io跳到了Express前面,接收/隐藏它想要的任何请求,这样Express就不会看到它们。

如果您好奇的话,下面是跳到http服务器所有侦听器前面的socket.io代码,从而绕过了express侦听器:

代码语言:javascript
运行
复制
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前缀,则手动调用前面的侦听器。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71905965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档