代码之家  ›  专栏  ›  技术社区  ›  Yousef Gamal

Express中间件未捕获套接字的请求事件。木卫一

  •  0
  • Yousef Gamal  · 技术社区  · 2 年前

    我在用 表示 (v4.17.3), 插座木卫一 ,和节点。Js的 http 单元我正在为 表示 捕获所有传入的请求,但这失败了。

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

    首先,下面是我指的代码。使用 表示 我正在尝试捕获所有传入的请求并记录它们,并对http执行同样的操作 on("request") .但是,请求将 插座木卫一 中间件不会捕获这些数据。

    // 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`)
    })
    

    当我得到/

    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() 根据(“请求”) (“快速请求=“&”Http请求=“)

    我的理解是:

    1-当我为 表示 正如下面的代码所示,任何传入的请求都应该先在这里捕获,然后再转到其他地方。(对吗?)

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

    2-当我路过 快速应用 作为http createServer ,即 快速应用 将被视为倾听者和任何 request 事件将传递给它。(对吗?)

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

    那么,如果我的理解是正确的,为什么请求事件捕获的所有请求都没有传递给中间件呢?

    2 回复  |  直到 2 年前
        1
  •  1
  •   jfriend00    2 年前

    这很正常。插座io将自己放在express(或http服务器上任何其他传入请求的侦听器)前面,以便在express看到请求之前接收请求。因此,Express(或其中间件)永远不会看到任何套接字。io连接请求。

    插座木卫一有自己的优势 own middleware layer 您可以使用它来参与套接字的初始化。io请求。

    或者,您可以注册接收套接字。与的io连接(已连接后调用) io.on('connection', ...) 事件处理程序。

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

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

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

    的确如此。但是插座。io跳到Express前面,接受/隐藏它想要的任何请求,以便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 事件本身,如果是套接字。io请求,则它不会调用之前的侦听器。如果不是插座。io前缀,然后手动调用之前的侦听器。

        2
  •  0
  •   Samay    2 年前

    我相信你需要记录socket上发送的消息。

    io.on('connection', (socket) => { socket.on('chat message', (msg) => { console.log('message: ' + msg); }); });