我有表达/ 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'
});
}
});
});
答案 0 :(得分:13)
有多种方法可以与路径文件共享io
变量。
当您在路径文件中require()
时,将io
变量作为构造函数参数传递给它。
使用app.set("io", io)
,以便您可以在任何有权访问let io = app.get("io")
对象的文件中使用app
。
创建一个中间件,将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);
答案 1 :(得分:1)
分享我使用过的解决方案
这个问题的另一个解决方案(我实际使用过)是我们可以使我们的 io
(socket.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