【发布时间】:2018-10-28 10:58:44
【问题描述】:
以下是我的 node.js 应用程序中的 server.js 文件。我希望服务器上的其他文件可以访问我的 socket.io 实例,以便从我的 API (listingRoutesApi, userRoutesApi etc.) (refer to code) 发出事件。
我的问题是我的路由是在创建服务器之前声明的;但是,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 实例。
此外,我认为我面临的挑战是一个非常普遍的挑战;但是,我找不到很多解决方案来解决它,也没有一个建议使用全局变量。
【问题讨论】:
-
@estus 你认为使用全局变量会遇到什么问题?
-
尝试搜索“为什么全局变量在 js 中不好”。你会有一大堆问题。 Node.js 引入模块正是为了摆脱不适合的全局变量。
标签: node.js websocket socket.io