gpt4 book ai didi

node.js - 我应该使用全局变量在整个服务器上共享 socket.io 实例吗

转载 作者:太空宇宙 更新时间:2023-11-03 23:17:57 24 4
gpt4 key购买 nike

以下是我的 node.js 应用程序中的 server.js 文件。我希望我的 socket.io 实例能够被服务器上的其他文件访问,以便从我的 API (listingRoutesApi、userRoutesApi 等)发出事件(引用代码)

我遇到的问题是我的路由是在创建服务器之前声明的;但是,socket.io 实例是在服务器创建之后创建的。

我使用的解决方案是声明一个全局 io 变量,它允许我从网络应用程序中的任何位置发出事件,如下所示:

global.io.of('/analytics').to(listing._id).emit('message', "There was a post.");

我的问题是:这样做是否存在任何陷阱/危险?从长远来看,我会遇到任何可扩展性问题吗?此外,有更好的方法来实现我的目标吗?

我的 server.js 文件中的代码:

const app = express();    

app.use('/api', listingRoutesApi);
app.use('/api', userRoutesApi);
app.use('/api', imageRoutesApi);
// ...plenty more endpoints here...

app.use(serveStatic(path.join(__dirname, "/dist")));
app.use(history());
app.use(serveStatic(path.join(__dirname, "/dist")));

const server = app.listen(port, () => { console.log('server started ' + port); });

/* Start socket. */
global.io = socketio(server);

const analytics = global.io.of("/analytics");

analytics.on('connection', (socket) => {
socket.on('join', (data) => {
socket.join(data.room);
analytics.in(data.room).emit('message', `New user joined ${data.room}`);
});
socket.on('leave', (data) => {
analytics.in(data.room).emit('message', `User leaving ${data.room}`);
socket.leave(data.room);
});
socket.on('disconnect', () => {
console.log('user disconnected');
});
});

我从this SO post开始问这个问题通过声明 getIOInstance 函数并将其传递给所有需要它的模块来回答类似的问题。虽然它确实有效,但感觉不太优雅,而且似乎有点不必要,因为我希望我的应用程序中只会有一个 socket.io 实例。

此外,我认为我面临的挑战是一个非常常见的挑战;但是,我找不到很多解决方案来解决这个问题,也没有一个建议使用全局变量。

最佳答案

Node.js 是一个模块化环境。模块应该解决全局变量存在的一些缺陷。

模块自然会提供单例实例,以防只需要一个实例:

app.js

module.export = express();

server.js

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

// can go to app.js if configured but unlistened app is needed for reusability or testing
app.use(/* router */);

module.export = app.listen(...);

socketio.js

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

module.export = socketio(server);

index.js

const app = require('./app');
const io = require('./socketio');
...

Express 还提供了一个用于应用程序全局依赖项的容器,application settings table 。它可以在应用程序实例可用的任何地方使用,例如作为中间件内的 req.app.get(...) 。如果 Express 应用程序实例也是单例,那么在中间件之外访问 Express 应用程序实例也不会出现问题:

app.js

module.export = express();

index.js

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

app.use(/* router */);
...

const server = app.listen(...);
const io = socketio(server);

app.set('io', io);

// available as req.app.get('io') inside middlewares
// and as require('./app').get('io') outside them

关于node.js - 我应该使用全局变量在整个服务器上共享 socket.io 实例吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53030744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com