在文件之间从 socket.io 共享服务器

VGO*_*ive 4 javascript websocket node.js socket.io

我正在尝试能够从其他文件调用 io。重点是当用户进入房间或​​被io.sockets呼叫等时它不会更新。

服务器.js

var options = {
  key: fs.readFileSync('./certs/file.key'),
  cert: fs.readFileSync('./certs/file.crt'),
  requestCert: false
};
var app = express();
var server = require('https').createServer(options, app);
var io = require('socket.io').listen(server); io.origins('*:*');
global.io = io;

io.on('connection', function(socket) {  .. }
Run Code Online (Sandbox Code Playgroud)

我也试过;

module.exports.io
Run Code Online (Sandbox Code Playgroud)

然后从另一个文件

require('server.js').io
Run Code Online (Sandbox Code Playgroud)

这也不起作用,我想在一个文件中运行我的服务器,即服务器 js,我在这里处理每个传入的套接字等等。这是我尝试过的两件事,但它们都导致了同样的问题。

jfr*_*d00 7

有许多不同的方案可以io与其他模块共享中心变量(如您的变量)。这样做到底有什么意义取决于整体架构,您希望模块如何可重用等等……但所有这些都使用导入和导出的某种组合来在模块之间共享数据而不使用global.

在您的具体情况下,您可以做一些非常简单的事情:

服务器.js

const options = {
  key: fs.readFileSync('./certs/file.key'),
  cert: fs.readFileSync('./certs/file.crt'),
  requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('./socket.js').init(server);

io.on('connection', function(socket) {  .. }
Run Code Online (Sandbox Code Playgroud)

套接字.js

let io;
module.exports = {
    init: function(server) {
        // start socket.io server and cache io value
        io = require('socket.io').listen(server); io.origins('*:*');
        return io;
    }
    getio: function() {
        // return previously cached value
        if (!io) {
            throw new Error("must call .init(server) before you can call .getio()");
        }
        return io;
    }
}
Run Code Online (Sandbox Code Playgroud)

在其他想要访问 io 的模块中

const io = require('./socket.js').getio();
Run Code Online (Sandbox Code Playgroud)

在这里不用说,您必须先调用,.init(server)然后才能调用.getio()。这利用了 node.js 模块缓存系统,因此每次调用require('./socket.js')它时都会返回第一次加载的相同模块,因此您可以访问先前缓存的io实例。


仅供参考,这称为“拉”模型,其中想要访问其他内容的模块使用require()语句来“拉”它想要的变量。

还有一个推送模块,模块的加载器在加载模块后通过调用该模块中的函数将数据推送到模块。


以下是其他一些方法:

从 app.js 导出

您必须注意此方案的循环依赖关系,因为如果 app.js 执行require('./a.js')然后a.js执行 require('./app.js') , you can create a circular dependency which will fail. So, this model only works ifa.js is doing arequire('./app.js')` 在模块加载后(如一个模块构造函数)。

应用程序.js

const options = {
  key: fs.readFileSync('./certs/file.key'),
  cert: fs.readFileSync('./certs/file.crt'),
  requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('socket.io').listen(server); io.origins('*:*');


io.on('connection', function(socket) {  .. }

// exports some things we want to share
module.exports  = {
  io: io,
  app: app
};
Run Code Online (Sandbox Code Playgroud)

其他一些想要访问 io 的文件

 // module constructor
 modules.exports = function() {
     // can use io in here
     const io = require('./app.js').io;
}
Run Code Online (Sandbox Code Playgroud)

推模型

在此模块中,您io可以在加载其他模块时将变量传递给需要它的任何其他模块。

应用程序.js

const options = {
  key: fs.readFileSync('./certs/file.key'),
  cert: fs.readFileSync('./certs/file.crt'),
  requestCert: false
};
const app = express();
const server = require('https').createServer(options, app);
const io = require('socket.io').listen(server); io.origins('*:*');


io.on('connection', function(socket) {  .. }

// load someotherfile.js and pass it the io variable
require('./someotherfile.js')(io);
Run Code Online (Sandbox Code Playgroud)

其他一些想要访问 io 的文件

module.exports = function(io) {
    // put whatever code for your module here
    setInterval(function() {
        io.emit(...);
    }, 1000);
}
Run Code Online (Sandbox Code Playgroud)