Javascript 在其他模块nodejs express中使用socket.io访问套接字发射器

Javascript 在其他模块nodejs express中使用socket.io访问套接字发射器,javascript,node.js,sockets,express,socket.io,Javascript,Node.js,Sockets,Express,Socket.io,首先,我要说我对nodejs基本上是新手。来自C的世界,这对我来说是一种完全不同的思维方式。 我已经完成了一些课程,我正在建立一个小网站,作为对自己的一种测试。我失败了 我将socket.io与node一起使用,并尝试每隔一段时间用发射器广播一条消息。我现在不关心具体的插座点,尽管我将来会关心,所以这个插座的发射器应该向每个人开放 从其他模块访问io对象时遇到问题。 我将发布我的server.js文件,以及app/index.js、socket/index.js、helpers/index.js

首先,我要说我对nodejs基本上是新手。来自C的世界,这对我来说是一种完全不同的思维方式。 我已经完成了一些课程,我正在建立一个小网站,作为对自己的一种测试。我失败了

我将socket.io与node一起使用,并尝试每隔一段时间用发射器广播一条消息。我现在不关心具体的插座点,尽管我将来会关心,所以这个插座的发射器应该向每个人开放

从其他模块访问io对象时遇到问题。 我将发布我的server.js文件,以及app/index.js、socket/index.js、helpers/index.js和api/index.js。我希望,张贴这些将显示它应该如何工作

理想情况下,为了保持一致性,我希望在套接字模块中保留所有与套接字相关的项。现在,我正在尝试在helpers模块中运行一个方法,但理想情况下socket模块会更好

无论如何,server.js:

'use strict';
const express = require('express');
const app = express();
const cryptometers = require('./app');
const api = require('./app/api');
const fs = require('fs');
const sources = require('./app/api/sources.json');

app.set('port', process.env.PORT || 3000);
app.set('view engine', 'ejs');

app.use(express.static('public'));
app.use(cryptometers.session);
app.use('/', cryptometers.router);

cryptometers.ioServer(app).listen(app.get('port'), () =>{
    console.log('app listening on port ' + app.get('port'));

api.getData(sources[0].source, sources[0].url, app);
setInterval(function(){api.getData(sources[0].source, sources[0].url, app)}, 60000);

});
这里的标准票价。我刚刚添加了一个数据检索器,它每分钟调用一次api,更新数据库

app/index.js:

'use strict';

const config = require('./config');

// create an IO server instance
let ioServer = app => {
    app.locals.globalMarketCap = [];

    const server = require('http').Server(app);
    const io = require('socket.io')(server);
    io.set('transports', ['websocket']);

    io.use((socket, next) => {
        require('./session')(socket.request, {}, next);
    });
    require('./socket')(io,app);
    return server;
}


// turns router into a module
module.exports = {
    router: require('./routes')(),
    session: require('./session'),
    ioServer,

}
'use strict';
const h = require('../helpers');

module.exports = (io, app) => {

    io.of('/').on('connection', socket =>{
        console.log('socket.io connected to client');

        if(app.locals.globalMarketCap){
            socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap));
        }
    })
}
'use strict';
const router = require('express').Router();
const db = require('../db');

// iterate through the routes object and mount the routes
let _registerRoutes = (routes, method) => {
    for(let key in routes){
        if(typeof routes[key] === 'object' && routes[key] !== null && !(routes[key] instanceof Array)){
            _registerRoutes(routes[key], key);
        } else {
            // Register the routes
            if(method === 'get'){
                router.get(key, routes[key]);
            } else if(method === 'post'){
                router.post(key, routes[key]);
            } else {
                router.use(routes[key]);
            }
        }
    }
}

let route = routes => {
    _registerRoutes(routes);
    return router;
}

let updateGlobalMarketCap = (app) =>{
   //app.io.socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap))
}

module.exports = {
    route,
    updateGlobalMarketCap
}
我正在初始化socket.io,并将其绑定到应用程序。它也是我初始化本地数据存储阵列的地方。这是做这件事的好地方吗

socket/index.js:

'use strict';

const config = require('./config');

// create an IO server instance
let ioServer = app => {
    app.locals.globalMarketCap = [];

    const server = require('http').Server(app);
    const io = require('socket.io')(server);
    io.set('transports', ['websocket']);

    io.use((socket, next) => {
        require('./session')(socket.request, {}, next);
    });
    require('./socket')(io,app);
    return server;
}


// turns router into a module
module.exports = {
    router: require('./routes')(),
    session: require('./session'),
    ioServer,

}
'use strict';
const h = require('../helpers');

module.exports = (io, app) => {

    io.of('/').on('connection', socket =>{
        console.log('socket.io connected to client');

        if(app.locals.globalMarketCap){
            socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap));
        }
    })
}
'use strict';
const router = require('express').Router();
const db = require('../db');

// iterate through the routes object and mount the routes
let _registerRoutes = (routes, method) => {
    for(let key in routes){
        if(typeof routes[key] === 'object' && routes[key] !== null && !(routes[key] instanceof Array)){
            _registerRoutes(routes[key], key);
        } else {
            // Register the routes
            if(method === 'get'){
                router.get(key, routes[key]);
            } else if(method === 'post'){
                router.post(key, routes[key]);
            } else {
                router.use(routes[key]);
            }
        }
    }
}

let route = routes => {
    _registerRoutes(routes);
    return router;
}

let updateGlobalMarketCap = (app) =>{
   //app.io.socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap))
}

module.exports = {
    route,
    updateGlobalMarketCap
}
在这里,我响应连接事件,并推出我在上面的最后一个文件中定义的数据数组。同样,理想情况下,我希望所有插座类型的东西都留在这里

helpers/index.js:

'use strict';

const config = require('./config');

// create an IO server instance
let ioServer = app => {
    app.locals.globalMarketCap = [];

    const server = require('http').Server(app);
    const io = require('socket.io')(server);
    io.set('transports', ['websocket']);

    io.use((socket, next) => {
        require('./session')(socket.request, {}, next);
    });
    require('./socket')(io,app);
    return server;
}


// turns router into a module
module.exports = {
    router: require('./routes')(),
    session: require('./session'),
    ioServer,

}
'use strict';
const h = require('../helpers');

module.exports = (io, app) => {

    io.of('/').on('connection', socket =>{
        console.log('socket.io connected to client');

        if(app.locals.globalMarketCap){
            socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap));
        }
    })
}
'use strict';
const router = require('express').Router();
const db = require('../db');

// iterate through the routes object and mount the routes
let _registerRoutes = (routes, method) => {
    for(let key in routes){
        if(typeof routes[key] === 'object' && routes[key] !== null && !(routes[key] instanceof Array)){
            _registerRoutes(routes[key], key);
        } else {
            // Register the routes
            if(method === 'get'){
                router.get(key, routes[key]);
            } else if(method === 'post'){
                router.post(key, routes[key]);
            } else {
                router.use(routes[key]);
            }
        }
    }
}

let route = routes => {
    _registerRoutes(routes);
    return router;
}

let updateGlobalMarketCap = (app) =>{
   //app.io.socket.emit('globalMarketCap', JSON.stringify(app.locals.globalMarketCap))
}

module.exports = {
    route,
    updateGlobalMarketCap
}
updateGlobalMarketCap的注释行是我的痛苦所在。正在尝试访问那里的io对象

api/index.js

'use strict';

const axios = require("axios");
const db = require("../db");
const h = require("../helpers");

let getData = (source, url, app, cryptoMeters) => {
    axios
        .get(url)
        .then(response => {
            //console.log(response.data);
            response.data["source"] = source;
            var data = new db.globalMarketCapModel(response.data);
            app.locals.globalMarketCap = response.data;
            var query = { source: source};

            db.globalMarketCapModel.findOne({
                "source":source
            }, 'source old_total_market_cap_usd total_market_cap_usd', function(err, market) {
                if (market) {
                    if(market.old_total_market_cap_usd != response.data.total_market_cap_usd
                    && market.total_market_cap_usd != response.data.total_market_cap_usd){
                        response.data["old_total_market_cap_usd"] = market.total_market_cap_usd;
                        h.updateGlobalMarketCap(app);
                    }

                    db.globalMarketCapModel.update(query, response.data, function (err) {
                        if (err) {
                            console.log("uhoh")
                        } else {
                            return true;
                        }
                    });
                } else {
                    data.save(function (err) {
                        if (err) {
                            console.log("uhoh")
                        } else {
                            return true;
                        }
                    })
                }
            })

            return true;
        })
        .catch(error => {
            console.log(error);
            return false;
        });
}


module.exports = {
    getData

}
这里的getData函数是调用更新发射器的地方

我曾考虑使用标准节点事件发射器来解决我的问题,但这可能会使工作变得一团糟,还有一个更简单的答案。
无论如何,谢谢你的阅读,我对目前为止我所写的任何评论都感兴趣。陷阱、错误等。在这里学习!:

有许多不同的方法来组织代码以实现io对象的共享。这里有一个这样的计划。您可以将socket.io初始化代码分解到它自己的模块中。您为该模块提供了两个主要功能:

将服务器传递到的构造函数,它允许socket.io在服务器上初始化自身

初始化io实例后获取该实例的方法

这将允许项目中希望访问io对象的任何其他代码执行以下操作:

const io = require('./io.js').getIO();
const io = require('./io.js')(server);
以下是io模块的结构:

// io.js

// singleton instance of socket.io that is stored here after the 
// constructor function is called
let ioInstance;

modules.exports = function(server) {
    const io = require('socket.io')(server);
    io.set('transports', ['websocket']);

    io.use((socket, next) => {
        require('./session')(socket.request, {}, next);
    });
    // save in higher scope so it can be obtained later
    ioInstance = io;
    return io;
}

// this getIO method is designed for subsequent 
// sharing of the io instance with other modules once the module has been initialized
// other modules can do: let io = require("./io.js").getIO();
module.exports.getIO() {
    if (!ioInstance) {
        throw new Error("Must call module constructor function before you can get the IO instance");
    }
    return ioInstance;
}
并且,该模块的初始化如下所示:

const io = require('./io.js').getIO();
const io = require('./io.js')(server);

您将其传递给web服务器,以便它能够连接到该服务器。在任何人都可以使用.getIO之前,它必须像这样初始化。ioInstance模块中的存储使用模块缓存。模块初始化代码只运行一次。之后,每次都会返回相同的导出,这些导出可以访问模块内保存的ioInstance。

您需要对象的引用。您可以将其传递给其他人,将其固定到/作为一个全局对象,或者通过修改缓存将模块包装为支持将来需要的持久性的内容。