为 socket.io 导出 HTTP 服务器无效
Exporting HTTP server for socket.io not working
我有一个app.js
const express = require('express');
const app = express();
const server = require('./server.js');
// app.use
const io = require('socket.io').listen(server);
io.on('connection', function (socket) {
...
});
module.exports = app;
还有一个server.js
const app = require('./app');
const server = app.listen(5000 || process.env.PORT, () => {
console.log('App listening on port 5000!');
})
module.exports = server;
如果我将服务器放在一个单独的文件中,则套接字无法正常工作,但如果我在 app.js
中启动服务器,则套接字可以正常工作。
我做错了什么?
这里的问题是您有一个循环依赖,其中 app.js
正在加载 server.js
并且 server.js
正在加载 app.js
。您不能为此类代码执行此操作。
它有一个问题,因为您试图从 app.js
中加载 server.js
,然后在加载 server.js
的过程中,它尝试加载 app.js
并获取它的导出,但是 app.js
还没有完成加载,因此甚至还没有返回它的导出。因此,加载程序认为没有导出或识别循环请求(我不确定是哪个),但在任何一种情况下,app.js
的导出都不起作用,因为循环要求。
有几种不同的方法可以解决这个问题。最常见的两种方式是:
将一些代码分解成一个通用的第三个模块,每个模块都可以加载,并且只有一个可以加载另一个。
与其让 server.js
加载 app
来获取 app
对象,不如让 app.js
将 app
对象传递给 server.js
在构造函数中,而不是尝试在模块加载时执行。
以下是构造函数想法的工作原理:
app.js
const express = require('express');
const app = express();
// load server.js and call it's constructor, passing the app object
// that module constructor function will return the server object
const server = require('./server.js')(app);
// app.use
const io = require('socket.io').listen(server);
io.on('connection', function (socket) {
...
});
module.exports = app;
server.js
// export constructor function that must be called to initialize this module
module.exports = function(app) {
const server = app.listen(5000 || process.env.PORT, () => {
console.log('App listening on port 5000!');
});
return server;
};
因此,不是 server.js
尝试加载 app.js
模块来获取 app
对象,app
对象是 "pushed"构造函数。这可以防止循环依赖。
我有一个app.js
const express = require('express');
const app = express();
const server = require('./server.js');
// app.use
const io = require('socket.io').listen(server);
io.on('connection', function (socket) {
...
});
module.exports = app;
还有一个server.js
const app = require('./app');
const server = app.listen(5000 || process.env.PORT, () => {
console.log('App listening on port 5000!');
})
module.exports = server;
如果我将服务器放在一个单独的文件中,则套接字无法正常工作,但如果我在 app.js
中启动服务器,则套接字可以正常工作。
我做错了什么?
这里的问题是您有一个循环依赖,其中 app.js
正在加载 server.js
并且 server.js
正在加载 app.js
。您不能为此类代码执行此操作。
它有一个问题,因为您试图从 app.js
中加载 server.js
,然后在加载 server.js
的过程中,它尝试加载 app.js
并获取它的导出,但是 app.js
还没有完成加载,因此甚至还没有返回它的导出。因此,加载程序认为没有导出或识别循环请求(我不确定是哪个),但在任何一种情况下,app.js
的导出都不起作用,因为循环要求。
有几种不同的方法可以解决这个问题。最常见的两种方式是:
将一些代码分解成一个通用的第三个模块,每个模块都可以加载,并且只有一个可以加载另一个。
与其让
server.js
加载app
来获取app
对象,不如让app.js
将app
对象传递给server.js
在构造函数中,而不是尝试在模块加载时执行。
以下是构造函数想法的工作原理:
app.js
const express = require('express');
const app = express();
// load server.js and call it's constructor, passing the app object
// that module constructor function will return the server object
const server = require('./server.js')(app);
// app.use
const io = require('socket.io').listen(server);
io.on('connection', function (socket) {
...
});
module.exports = app;
server.js
// export constructor function that must be called to initialize this module
module.exports = function(app) {
const server = app.listen(5000 || process.env.PORT, () => {
console.log('App listening on port 5000!');
});
return server;
};
因此,不是 server.js
尝试加载 app.js
模块来获取 app
对象,app
对象是 "pushed"构造函数。这可以防止循环依赖。