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

时间:2017-12-15 18:07:52

标签: javascript node.js sockets express

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

在server.js文件中,我也通过监听特定端口(如3000)来启动快速服务器。

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'
            });
        }
    });
});

3 个答案:

答案 0 :(得分:13)

有多种方法可以与路径文件共享io变量。

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

  2. 使用app.set("io", io),以便您可以在任何有权访问let io = app.get("io")对象的文件中使用app

  3. 创建一个中间件,将io对象放在每个req对象上,这样您就可以随时访问它。

  4. 以下是将其作为构造函数参数传递给路由器文件的示例:

    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);
    

答案 1 :(得分:1)

分享我使用过的解决方案

这个问题的另一个解决方案(我实际使用过)是我们可以使我们的 iosocket.io 对象)对象全局化。

只需将 io 分配给 global.io

io 对象在 index.js 中,创建并设置 io 对象后只需执行 global(即 global.io = io;),现在这个 {{ 1}} 对象可以通过我们在项目中工作的任何路径访问。

答案 2 :(得分:0)

在server.js中:

module.exports.getIO = function(){
     return io;
}

在你的路线档案中:

var theServer = require('<path to server.js>');
var iovar = theServer.getIO(); //your io var