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

2024-04-24

以下是我的 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');
    });
});

我问这个问题是因为这个帖子 https://stackoverflow.com/questions/36676815/nodejs-socketio-multiple-files通过声明来回答类似的问题getIOInstance函数并将其传递给所有需要它的模块。虽然它确实有效,但感觉不是很优雅,而且似乎有点不必要,因为我希望我的应用程序中只会有一个 socket.io 实例。

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


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

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

app.js

module.export = express();

服务器.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还提供了应用程序全局依赖项的容器,应用程序设置表 https://expressjs.com/en/api.html#app.set。它可以在应用程序实例可用的任何地方使用,例如作为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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该使用全局变量在整个服务器上共享 socket.io 实例吗 的相关文章

随机推荐

  • F# 中的异步 EF 查询

    在使用 EF6 的 C 中 我可以轻松地进行如下异步操作 using var context new MyDbContext var item await context SomeEntities Where e gt e Id 1 Fir
  • 如何在窗口窗体中制作圆形标签?

    众所周知 标签通常是正方形或长方形 我真的需要制作圆形标签 谁能告诉我这是否可能 或者至少为我指出正确的方向 抱歉 只是为了把事情说清楚 我想要一个圆形标签 不仅仅是在屏幕上画一个圆圈 您可以设置 Label 的 Region 属性 var
  • 在 CentOS 6.4 中意外删除了符号链接 libc.so.6。如何获得 sudo 权限来重新创建它?

    我不小心删除了符号链接 lib64 libc so 6 gt lib64 libc 2 12 so sudo rm libc so 6 然后我不能使用任何东西 包括ls命令 我输入的任何命令都会出现错误 ls error while loa
  • 如何使用 USPS 验证给定地址?

    我想向 USPS 验证给定的地址 地址 城市 州 邮政编码 如果提供的地址是有效地址 则返回结果 如果不是有效地址 则返回无效地址 那么我怎样才能在 C Net 中做到这一点呢 美国邮政服务 USPS 通过其地址信息 API 提供此服务 U
  • 扁平按钮与凸起按钮

    我想知道之间的基本区别Flat button and Raised Button 根据新Android材料设计指南 我想使用凸起按钮 但我不知道它们是什么 网络上有一些论坛显示一个凸起的按钮 但他们称之为 扁平 谁能告诉我两者之间的基本区别
  • Android 找不到类异常

    我正在使用两个单独的类 其中一个有一些按钮 另一个打开谷歌地图 我正在其上进行覆盖 如果有人能看到我打开 Map class 的意图的问题 请告诉我 我将输入我的错误消息和代码 package com state park import j
  • ORM 是用于迁移数据的正确工具吗?

    背景 我们正在升级旧版导入工具 它的作用是将数据从连接到 SQL Server 的一个数据库移动到同一服务器上的第二个数据库 并使用不同的模式沿途执行转换和映射 这是一个帮助解释正在发生的事情的示例 假设源数据库有一张表名为Client I
  • Java - 点在线

    我如何找出点 x y 是否位于其他两个点之间创建的线上 我尝试了这个 但似乎有些问题 因为我没有得到我应该得到的结果 public boolean intersects Point k Point z Point p Line2D line
  • Jackson 或 JAXB,哪一个更适合 JSON? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我想知道 JSON Jackson 或 JAXB 哪一个更好 我做了一些研究 我知道 也许我错了 我们不应该使用 JAXB 来转换 JSON 某
  • 比较当前月份和上个月的列上的行,SQL Server 2012

    我需要一些指导和帮助来解决我不完全确定如何在 SQL Server 2012 中解决的问题 我认为LAG and LEAD函数可能有用 但我不确定 这就是我的数据现在的样子 YearMonth LocationCode Active 201
  • 是否可以使用文件名模式创建 blob 触发的 azure 函数?

    我正在开发一个 blob 触发的 azure 函数 以下是我的 function json 文件的配置 disabled false bindings name myBlob type blobTrigger direction in pa
  • 如何在 CKEditor 中更改已注册的对话框

    我正在尝试编写一个插件 向图像对话框添加一个附加选项卡 页面 我不想更改对话框的源本身 而是使用插件来增强它 我搜索文档和论坛已经有一段时间了 现在我知道我可以在对话框对象上调用 addPage 来添加另一个选项卡 我也了解内容对象必须是什
  • 识别 Pandas 数据框中组中重复项的更好方法? [复制]

    这个问题在这里已经有答案了 我有一个数据框 x c 0 0 1 1 3 2 2 1 1 3 2 1 4 3 1 5 4 1 6 1 0 7 3 1 8 2 1 9 1 2 我想生产 c x duplicated 0 1 0 False 1
  • 如何交错或创建两个字符串的唯一排列(无需递归)

    问题是打印两个给定字符串的所有可能的交错 所以我用 Python 编写了一个工作代码 其运行如下 def inter arr1 arr2 p1 p2 arr thisarr copy arr if p1 len arr1 and p2 le
  • 如何动态更改母版页

    我想为一个纯aspx文件动态分配一个母版页 任何人都可以告诉我 如何做到这一点 您可以覆盖 default aspx cs 中的 OnPreInit 并根据查询字符串中的某些值设置母版页 像这样的事情 protected override
  • 什么是低位和高位?

    谁能告诉我什么是低位和高位 如何识别高位和低位 下面是二进制形式 如何0110里面有更高位吗 0110 0111 1100 1010 1100 0111 1001 1011 就像十进制一样 二进制中较高位通常写在左侧 所以如果你看到0111
  • pandas.concat 和 numpy.append 大数据集的内存错误

    我面临一个问题 我必须在循环中生成大型 DataFrame 每次两个 2000 x 800 pandas DataFrame 时进行 50 次迭代计算 我想将结果保存在内存中更大的 DataFrame 中 或者保存在类似字典的结构中 使用
  • 查找 Java Enum 的最佳实践

    我们有一个 REST API 客户端可以提供代表服务器上 Java 枚举中定义的值的参数 所以我们可以提供一个描述性错误 我们添加这个lookup每个枚举的方法 看起来我们只是在复制代码 不好 有更好的做法吗 public enum MyE
  • AWS - t2.micro 实例 EBS 卷大小

    我试图通过 AWS 控制台创建 t2 micro 实例 我希望它免费一年 但它不附带任何实例存储 所以我想在这个实例中添加 EBS 卷 免费吗 我可以在 t2 micro 中免费添加的最大 EBS 卷是多少 Model vCPU CPU C
  • 我应该使用全局变量在整个服务器上共享 socket.io 实例吗

    以下是我的 node js 应用程序中的 server js 文件 我希望我的 socket io 实例能够被服务器上的其他文件访问 以便从我的 API 发出事件 listingRoutesApi userRoutesApi etc ref