node.js - 如何在没有 redis 的情况下扩展 socket.io

标签 node.js express socket.io

我目前正在寻找一种替代方案来使用 socket.io 扩展我的 Express 应用程序。问题是我不想使用 redis 作为 socket.io 存储。除了 Clusterhub 之外,是否还有其他可能性来集群 socket.io ?

编辑:我尝试使用fakeredis作为redis的替代品,但它似乎不适用于socket.io。来自 ActionHero.js我知道 faye-websocket 可以与 fakeredis 配合使用。

最佳答案

这很可能取决于您的 socket.io 使用情况以及您想要实现的扩展类型(集群与扩展到多台机器)。

所以,这就是我将 socket.io 的使用扩展到多个服务器的方法。

我们在负载均衡器后面有 3 个服务器,当套接字连接时,它会连接到 3 个服务器中的任何一个,这三个服务器在内存中有一个套接字列表,并且这三个服务器有一个内部服务器地址的顺序列表,例如[服务器1、服务器2、服务器3]。

我所做的基本上是一个环(在内部我们称之为“套接字环”):

  • 如果我需要从 server1 向套接字发出事件,我首先查看套接字是否连接到该 server1,如果没有,我会向下一个服务器 (server2) 发送一个 http 请求,该服务器将检查套接字是否存在,如果不存在,它将向 server3 发送相同的请求,依此类推,直到到达源点,在这种情况下,您可能会抛出错误。
  • 如果我需要广播消息,这几乎是一样的,我从一台服务器开始,然后调用其他服务器上的 http 端点。

我用来确定下一个 Node (next_node.js)的算法是:

var nodes = process.env.NODES.split(',');
//this is usually:  http://server1/,http://server2/,http://server3/

var url = require('url');
var current = require("os").hostname();

//origin is the node that started the lookup
exports.get = function (origin) {
  var next_node_i = nodes.map(function (uri) {
    return url.parse(uri).hostname;
  }).reduce(function (prev, curr, i, arr){
    return curr === current && i < arr.length - 1 ? i + 1 : prev;
  }, 0);

  var next_node = nodes[next_node_i];

  if (origin && url.parse(next_node).hostname === origin) {
    // if the next node is equal to the first node initiating the lookup
    // it means the socket we are looking for is not connect to any node.
    return null;
  }

  return next_node;
};

注意事项:

  • 这些服务器之间的延迟很低,并且不太可能出现网络分区,它们物理上位于同一数据中心。但如果是网络分区对我们来说就没那么重要了。
  • 我们总是朝同一个方向跑圈。改进的版本将是双向运行(?)
  • 服务器共享一个 secret 来调用这些端点。

在我看来,这是在许多 socket.io 用例中实现扩展的一种非常简单的方法,可能在很多其他场景中这不是一个选项,但我希望这能提供一些想法。

关于node.js - 如何在没有 redis 的情况下扩展 socket.io,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21604041/

相关文章:

express - 将 Stripe webhooks 与 graphql-yoga 和 Prisma 结合使用

node.js - 使用 Require.js 在离线应用程序中引用 Node 服务器的 Socket.io

javascript - react 生产构建, Assets 未加载

javascript - Electron Node 集成不起作用,也是一般奇怪的 Electron 行为

javascript - 如何在javascript中基于字符串数组创建嵌套数组?

javascript - 仅导入一个函数是否也会运行该文件中的其他函数?

javascript - 对象的属性未定义

javascript - 在 chrome 上运行的 Sails 中出现错误 "transport unknown"

ios - iOS 中后台服务不会停止

javascript - Node.JS 上的静态 Web 部署,无需使用任何框架