模块化node.js / socket.io / express应用程序的最佳方法

时间:2022-08-22 14:37:46

I'm currectly creating an app using Node.JS that makes use of Express and Socket.io. As time progresses it's becoming increasingly difficult to deal with one file, I'm in the process of moving certain things out that I know how but was wondering on the best approach to do this.

我现在正在使用Node.JS创建一个使用Express和Socket.io的应用程序。随着时间的推移,处理一个文件变得越来越困难,我正在移动某些事情,我知道如何但是想知道最好的方法来做到这一点。

I have a private area constructor similar to:

我有一个类似于的私有区域构造函数:

privateArea.js

function privateArea(props) {
    this.id = props.id;
    this.name = props.name;
    this.users = [];
}

privateArea.prototype.addUser = function(socketId) {
    this.users.push(socketId);
};

module.exports = privateArea;

I'd like to have this also have access to the socket.io variable that's been setup for use in a separate sockets.js file that can be included via the main app.js and a seperate file for express.js

我想让它也可以访问socket.io变量,该变量已被设置用于单独的sockets.js文件,该文件可以通过主app.js和express.js的单独文件包含在内

So I'd like the structure as follows:

所以我想结构如下:

project
| app.js - joins it all together
| express.js - initialises and manages all express routing
| privateArea.js - constructor for private areas - must be able to reference socket.io
| sockets.js - initialises and manages all socket.io sockets and events

Any help/examples would be very appreciated.

任何帮助/示例将非常感激。

Thanks

1 个解决方案

#1


2  

I use socket.io and express quite often in my projects, and I've developed a template which makes things easy. I like to have a fail-over in case the socket connections drops for some reason, or if a socket connection cannot be established. So I create http channels as well as socket channels. Here's a basic module template:

我使用socket.io并在我的项目中经常表达,并且我开发了一个简化模板的模板。我喜欢在套接字连接由于某种原因而丢失的情况下进行故障转移,或者如果无法建立套接字连接。所以我创建了http通道以及套接字通道。这是一个基本的模块模板:

module.exports = function () {
    var exported = {};

    var someFunction = function (done) {
        //.. code here..//
        if (typeof done === "function") {
            done(null, true);
        }
    };
    // export the function
    exported.someFunction = someFunction;

    var apicalls = function (app) {
        app.get("/module/someFunction", function (req, res) {
             res.header("Content-Type", "application/json");
             someFunction(function (err, response) {
                 if (err) return res.send(JSON.stringify(err));
                 res.send(JSON.stringify(response));
             });
        });
    };
    exported.apicalls = apicalls;

    var socketcalls = function (io) {
        io.on("connection", function (socket) {
            socket.on('module-someFunction', function () {
                someFunction(function (err, response) {
                    if (err) return socket.emit('module-someFunction', err);
                    socket.emit('module-someFunction', response);
                });
            });
        });
    };
    exported.socketcalls = socketcalls;

    return exported;
}

So to use this, I'd first need to include the module in my app.js file like this:

所以要使用它,我首先需要将模块包含在我的app.js文件中,如下所示:

var mymod = require('./myModule.js');

And then I can enable access to this service from HTTP and over the websocket like this:

然后我可以通过HTTP和websocket启用对此服务的访问,如下所示:

mymod.apicalls(app);   // passing express to the module
mymod.socketcalls(io); // passing socket.io to the module

Finally, from the front-end, I can check to see if I have a socket connection, and if so, I use the socket to emit "module-someFunction". If I don't have a socket connection, the front-end will do an AJAX call instead to "/module/someFunction" which will hit the same function on the server side that it would've had I used the socket connection.

最后,从前端,我可以检查是否有套接字连接,如果有,我使用套接字发出“module-someFunction”。如果我没有套接字连接,前端将执行AJAX调用而不是“/ module / someFunction”,它将在服务器端执行与使用套接字连接时相同的功能。

As an added bonus, if I need to utilize the function within the server, I could do that as well since the function is exported. That would look like this:

作为一个额外的好处,如果我需要在服务器中使用该功能,我也可以这样做,因为导出该功能。这看起来像这样:

mymod.someFunction(function (err, response) {
    // ... handle result here ... //
});

#1


2  

I use socket.io and express quite often in my projects, and I've developed a template which makes things easy. I like to have a fail-over in case the socket connections drops for some reason, or if a socket connection cannot be established. So I create http channels as well as socket channels. Here's a basic module template:

我使用socket.io并在我的项目中经常表达,并且我开发了一个简化模板的模板。我喜欢在套接字连接由于某种原因而丢失的情况下进行故障转移,或者如果无法建立套接字连接。所以我创建了http通道以及套接字通道。这是一个基本的模块模板:

module.exports = function () {
    var exported = {};

    var someFunction = function (done) {
        //.. code here..//
        if (typeof done === "function") {
            done(null, true);
        }
    };
    // export the function
    exported.someFunction = someFunction;

    var apicalls = function (app) {
        app.get("/module/someFunction", function (req, res) {
             res.header("Content-Type", "application/json");
             someFunction(function (err, response) {
                 if (err) return res.send(JSON.stringify(err));
                 res.send(JSON.stringify(response));
             });
        });
    };
    exported.apicalls = apicalls;

    var socketcalls = function (io) {
        io.on("connection", function (socket) {
            socket.on('module-someFunction', function () {
                someFunction(function (err, response) {
                    if (err) return socket.emit('module-someFunction', err);
                    socket.emit('module-someFunction', response);
                });
            });
        });
    };
    exported.socketcalls = socketcalls;

    return exported;
}

So to use this, I'd first need to include the module in my app.js file like this:

所以要使用它,我首先需要将模块包含在我的app.js文件中,如下所示:

var mymod = require('./myModule.js');

And then I can enable access to this service from HTTP and over the websocket like this:

然后我可以通过HTTP和websocket启用对此服务的访问,如下所示:

mymod.apicalls(app);   // passing express to the module
mymod.socketcalls(io); // passing socket.io to the module

Finally, from the front-end, I can check to see if I have a socket connection, and if so, I use the socket to emit "module-someFunction". If I don't have a socket connection, the front-end will do an AJAX call instead to "/module/someFunction" which will hit the same function on the server side that it would've had I used the socket connection.

最后,从前端,我可以检查是否有套接字连接,如果有,我使用套接字发出“module-someFunction”。如果我没有套接字连接,前端将执行AJAX调用而不是“/ module / someFunction”,它将在服务器端执行与使用套接字连接时相同的功能。

As an added bonus, if I need to utilize the function within the server, I could do that as well since the function is exported. That would look like this:

作为一个额外的好处,如果我需要在服务器中使用该功能,我也可以这样做,因为导出该功能。这看起来像这样:

mymod.someFunction(function (err, response) {
    // ... handle result here ... //
});