首先,我要说我对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,
}
这里我正在初始化socket.io,将其绑定到应用程序。这也是我初始化本地数据存储阵列的地方。(这里是做这件事的好地方吗??)
socket/index.js:
'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));
}
})
}
这里我响应连接事件,并推出我在上面最后一个文件中定义的数据数组。再次强调,理想情况下,我希望所有的套接字类型的东西都留在这里。
helpers/index.js:
'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();
以下是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')(server);
将它传递给web服务器,这样它就可以挂接到web服务器上。在任何人可以在它上使用.getio()
之前,它必须像这样初始化。IOInstance
模块中的存储利用了模块缓存。模块初始化代码只运行一次。之后,每次返回相同的导出,这些导出可以访问模块中保存的IOInstance
。