当前位置: 首页 > 面试题库 >

在expressjs路由中而不是在主server.js文件中使用socket.io

许曦
2023-03-14
问题内容

我有express / nodejs
api。我要添加socket.io功能。目前,我所有的路线都在单独的文件夹中,我将它们包含在server.js文件中,并将其用作app.use()函数。

在server.js文件中,我还通过侦听特定端口(例如3000)来启动Express服务器,如下所示。

let server = app.listen(3000);

根据所有谷歌搜索,我发现我需要传递服务器变量来初始化socket.io,如下所示。

let io = require('socket.io')(server);

现在的问题是,由于它需要此变量,那么如何在不同文件夹中的路由文件中使用socket.io来发出和接收来自客户端的事件?

更新

在server.js文件中

let route = require('./routes/route');

let app = express();

let server = app.listen(3000);

console.log('Listening to port');

let io = require('socket.io')(server);

app.use('/api/1.0/events', route(io));

在route.js文件中

let express = require('express');

module.exports = (io) => {
    console.log('IO: ', io);
};

更新2

server.js文件

let express = require('express');
let events = require('./routes/events');
let app = express();
let server = app.listen(3000);

let io = require('socket.io')(server);


app.use(function(request, response, next) {
    request.io = io;
    next();
});

app.use('/events', events);

events.js文件

let express = require('express');

let Events = require('../models/events');

apiRoutes.post('/new', function(request, response) {
    let newEvent = new Events(request.body);

    newEvent.save((error, result) => {
        if (error) {
            response.json(error);
        } else {
            // console.log('ELSE');
            // request.io.on('connect', socket => {
                // console.log('LISTENING TO SOCKET...');

                request.io.on('EventCreated', data => {
                    console.log('DATA ON Server: ', data);
                });
            // });

            response.json({
                success: true,
                message: 'New event created'
            });
        }
    });
});

问题答案:

io与路由文件共享变量有多种方法。

  1. 当您require()在路由文件中时,将io变量作为构造函数参数传递给它。

  2. 使用app.set("io", io),然后可以let io = app.get("io")在可以访问该app对象的任何文件中使用。

  3. 创建一个将io对象放置在每个对象上的中间件,req以便您可以随时从那里访问它。

这是将其作为构造函数参数传递到路由器文件的示例:

let server = app.listen(3000);
let io = require('socket.io')(server);

// load other routers
app.use(require("./someRouterFile.js")(io));

// in someRouterFile.js
const express = require('express');

module.exports = function(io) {
    let router = express.Router()

    // define routes
    // io is available in this scope
    router.get(...)

    return router;
}

这是该app.set()方案的一个示例:

let server = app.listen(3000);
let io = require('socket.io')(server);
app.set("io", io);

然后,在您可以访问该app对象的路线中的任何位置,都可以使用以下方法获取它:

let io = app.get("io");

这是一个使用中间件将io对象设置到每个req对象上以便可以在所有路由中使用的示例。

let server = app.listen(3000);
let io = require('socket.io')(server);

// place this middleware before any other route definitions
// makes io available as req.io in all request handlers
app.use(function(req, res, next) {
    req.io = io;
    next();
});

// then in any express route handler, you can use req.io.emit(...)

这是在不使用中间件的情况下对模块构造函数使用参数的示例:

// in mysocket.js
module.exports = (io) => {
    console.log('IO: ', io);
    io.on('connect', socket => {
       // handle various socket connections here
    });

    // put any other code that wants to use the io variable
    // in here


};

然后,在您的主文件中:

let server = app.listen(3000);
let io = require('socket.io')(server);

// initialize my socketio module and pass it the io instance
require('./mysocket.js')(io);


 类似资料:
  • 问题内容: 我正在尝试将Socket.io与Node.js结合使用,并在路由逻辑内发送到套接字。 我有一个相当标准的Express 3安装程序,其中的server.js文件位于该路由中,然后我的index.js位于一个routes文件夹中,该文件夹导出站点的所有页面/公共可访问功能。因此,它们看起来像: 在server.js中定义的路由如下: 我假设我必须在server.js中创建socket.i

  • 问题内容: 我只想验证一下内容,但无法在Express文档或在线文档中找到与此相关的内容(尽管我知道这是一个功能)。 我可以对其进行测试,但我实际上并没有一个很好的模板,想听听社区的意见。 如果我这样定义快递路线: 我还可以定义一个中间件并直接加载它,例如 但是,我还可以链接这些路由中的至少一个来运行额外的中间件,例如身份验证,如下所示: 这些是无限可链接的吗?如果我愿意,可以在给定的路由上添加1

  • 问题内容: 我正在将node与express和passportjs一起使用,以限制对位于私有文件夹中的文件的访问。我将代码简化为以下内容。公共静态文件夹中的所有内容都可以正常工作,但通过使用staticMiddleware定位到私有文件夹的路由将返回404错误。 我使用的以下参考似乎对其他人有用,因此我一定会丢失一些东西。这对我来说不起作用,对于私有区域中的内容仅显示404响应。 我本可以发誓我以

  • 问题内容: 因为我想分离系统的前端和后端。我已经在控制器内部创建了2个文件夹作为前端和后端 下面是我的控制器文件夹的结构 我可以通过使用以下功能 但我想从网址中删除前端和后端段。 我检查了codeigniter中的路由功能,但据我所知,我需要分别指定每个路由。由于我大约有12个控制器,每个控制器都具有大约10 -15个功能,因此我可能必须指定该路由的每个功能。 有没有其他有效的方法可以实现使用路由

  • 问题内容: 我想读取一个远程图像并显示它。我可以保存文件,但无法正确显示代码。理想情况下,我只想尽管正确地传递文件但不进行处理- 不确定是否需要tmp文件步骤。此代码不显示任何内容-没有错误。我也尝试过res.pipe(response)。 问题答案: 好吧,我仍然想知道如何进行上述工作,但是我通过请求模块解决了我的问题!

  • 问题内容: 因此,我开始使用Node.js。我在Nodejs.org上与Ryan Dahl一起观看了视频,听说他向网站推荐了Express-js。 我下载了最新版本的Express,并开始编写代码。我在/上有一个完整的静态视图,但是一旦尝试发送参数,就会收到如下错误: 我尝试按照expressjs.com上的指南进行操作,但是在最新版本中,使用路由的方式已更改,这使该指南无法使用。 指南: 由Ex