使用 Socket.IO 发送数据的频率是多少?

2024-03-04

我正在创建一个 Web 应用程序,需要频繁地将少量数据(每个套接字 3 个整数值)从服务器发送到客户端,并且我想看看是否有使用更新客户端的最大频率套接字IO https://socket.io/.

我希望能够实现至少 50 个套接字连接,每个连接每秒发送 20 个更新。理想的数量是 200 个套接字连接,每秒发送 50 个更新。

问题:使用 Socket.IO 发送新数据的频率是否有限制?

注意:我认识到这也成为服务器-客户端连接的速度问题,因此任何有关我需要的连接速度的信息都值得赞赏。我计算出,如果发送的每个数据包大约为 500 字节,那么我将能够每秒发送 20 个更新,从而在 1 MB/s 连接上发送 100 个连接。


这是一个非常依赖系统、网络和代码的问题。

这是我之前用于类似的普通 socket.io 测试的一个小测试工具,我插入了一些位来满足您的问题。

Server

const io = require('socket.io')(8082)
const connections = []

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

  connections.push(socket);
  const slog = (msg, ...args) => console.log('%s %s '+msg, Date.now(), socket.id, ...args)
  slog('Client connected. Total: %s', connections.length)

  socket.on('disconnect', function(data){
    connections.splice(connections.indexOf(socket), 1);
    slog('Client disconnected. Total: %s', connections.length)
  })

  socket.on('single', function(data){
    socket.emit('single',[ 0, now, now, now ])
  })

  socket.on('start', function(data = {}){
    slog('Start stream', data)
    sendBatch(1, data.count, data.delay)
  })

  socket.on('start dump', function(data = {}){
    slog('Start dump', data)
    sendBatch(1, data.count)
  })

  function sendBatch(i, max, delay){
    if ( i > max ) return slog('Done batch %s %s', max, delay)
    socket.emit('batch',[ i, now, now, now ])
    if (delay) {
      setTimeout(()=> sendBatch(i++, max, delay), delay)
    } else {
      setImmediate(()=> sendBatch(i++, max))
    }
  }

})

Client

const io = require('socket.io-client')
const socket = io('http://localhost:8082', {transports: ['websocket']})

socket.on('connect_error', err => console.error('Socket connect error:', err))
socket.on('connect_timeout', err => console.error('Socket connect timeout:', err))
socket.on('reconnect', err => console.error('Socket reconnect:', err))
socket.on('reconnect_attempt', err => console.error('Socket reconnect attempt:', err))
socket.on('reconnecting', err => console.error('Socket reconnecting', err))
socket.on('reconnect_error', err => console.error('Socket reconnect error:', err))
socket.on('reconnect_failed', err => console.error('Socket reconnect failed:', err))

function batch(n){
  socket.on('batch', function(data){
    if ( data[0] >= n ) {
      let end = Date.now()
      let persec = n / (( end - start ) / 1000)
      console.log('Took %s ms for %s at %s/s', end - start, n, persec.toFixed(1))
      return socket.close()
    }
  })
}

function startDump(count = 500000){
  socket.emit('start dump', { count: count })
  console.log('Start dump', count)
  batch(count)
}
function startStream(count = 50, delay = 1000){
  socket.emit('start', { count: count, delay: delay })
  console.log('Start stream', count, delay)
  batch(count)
}

function pingIt(i, max = 50){
  socket.on('single', function(data){
    console.log('Got a single with:', data)
    if (i >= max) {
      let end = Date.now()
      let persec = i / (end - start) * 1000
      console.log('Took %s ms %s/s', end - start, persec.toFixed(2))
      return socket.close()
    }
    socket.emit('single', i+=1)
  })
  socket.emit('single', i)
}

let start = Date.now()

//console.log('args command: %s  count: %s  delay: %s',process.argv[2], process.argv[3], process.argv[4])
switch(process.argv[2]){
  case 'ping':   pingIt(0, process.argv[3]); break
  case 'stream': startStream(process.argv[3], process.argv[4]); break
  case 'dump':   startDump(process.argv[3]); break
  default:       console.log('ping stream dump'); socket.close()
}

测试请求/响应往返

 node socketio-client.js ping 4

要测试吞吐量,请以服务器最快的速度转储消息。

 node socketio-client.js dump 100000

测试 1000 条消息的流,每条消息之间有 18 毫秒的延迟,即每秒大约 50 条消息。

 node socketio-client.js stream 1000 18

在我的开发机器上,我可以每秒将大约 40000 条消息转储到单个本地主机客户端,并在 2 GHz CPU 上使用 4 个整数作为有效负载(计数器 + 3 个时间戳)。服务器和客户端都可以node每个进程使用 95-100% 的 CPU 核心。所以纯粹的吞吐量看起来还可以。

我可以在服务器进程的 CPU 使用率为 55% 的情况下每秒向 100 个本地客户端发送 100 条消息。

我无法从单个客户端向 100 个客户端每秒发送超过 130-140 条消息node我的开发机器上的进程。

新的高频 Intel Skylake CPU 服务器可能会在本地消除这些数字。添加一个可能不稳定的网络连接,它就会立即恢复正常。除了本地网络延迟之外的任何因素都可能会扰乱您认为通过如此高的消息速率获得的收益。任何较慢的延迟抖动都会对客户端消息的“帧速率”造成严重破坏。可能需要在客户端上对消息加时间戳并对其进行跟踪。

如果您确实遇到问题,还有较低级别的 websocket 库,例如ws https://github.com/websockets/ws这将需要您更多的实现,但会给您更多对套接字连接的控制,并且您可能会从中获得更多的性能。

连接越多,与其余代码和套接字代码的争用就越多。您可能最终需要使用多个节点 https://socket.io/docs/using-multiple-nodes/#让事情顺利进行。集群可以将应用程序拆分为多个 Node.js 进程 https://stackoverflow.com/q/18310635/1318694。你可能需要像Redis这样的东西,ZeroMQ http://zeromq.org/ or Nanomsg http://nanomsg.org/管理IPC。 Node 9 中的 V8 支持共享数组缓冲区 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer and Atomics https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics但 Node 上还没有多少东西可以与工人一起使用它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Socket.IO 发送数据的频率是多少? 的相关文章

随机推荐

  • 在 ARMv7 的上下文中,当 mmu 必须进行页表转换时,Linux 内核一对一映射内存的优势是什么

    Linux内核虚拟地址是一对一映射 所以通过减去一个PAGE OFFSET到虚拟地址我们将得到物理地址 就是那样virt to phys http lxr free electrons com source arch arm include
  • 如何使用Ajax和JSON制作下拉菜单?

    这是我用来显示类别菜单的代码OpenCart具有不同的级别 它有效 但每次点击后它都会产生越来越多的XHR finished loading POST and XHR finished loading GET有时通过单击来停止页面
  • HDINSIGHT hive,MSCK REPAIR TABLE table_name 抛出错误

    我有一个名为employee 的外部分区表 带有分区 年 月 日 每天都会有一个新文件出现在特定日期的位置 调用今天的日期 它将是2016 10 13 TABLE SCHEMA create External table employee
  • 在 ExpressJS + Reactjs 中传递数据以查看

    我有一个应用程序 其中一部分是用 Twitter 登录 成功登录后 我通常会将用户数据传递给模板 app get function req res next log The Home page has the user info req s
  • C# 依赖注入运行时(动态)注册

    我正在使用 VS 2017 和 NET Core 使用依赖注入 我想在运行时动态注册我的服务 我的目标是编写在单独的程序集中实现服务接口的服务实例 然后 服务名称 程序集名称将被添加到某种配置文件 或数据库表 中 我的注册代码会做这样的事情
  • OpenMP 中使用循环的并行部分

    我想知道是否有任何技术可以使用 for 循环在 OpenMp 中创建并行部分 例如 我不想创建 n 个不同的 pragma omp 部分 而是使用 n 次迭代来创建它们for loop每个部分都有一些变化的参数 pragma omp par
  • 如何处理具有不同布局的 Visual Studio 解决方案中的 Git 子模块?

    我们使用 Visual Studio 2010 C 进行开发 不久前从 SVN 迁移到 GIT 现在 我们尝试将我们的存储库 相当大 约 30 000 个文件 拆分为许多 git 存储库 每个解决方案一个 这些解决方案共享一些项目 主要是我
  • 无法让 Costura.Fody 工作,一直要求 DLL

    我已使用 nuget 包将 costura fody 安装到我的项目中 我已将 FodyWeavers xml 文件更新为
  • Binary(16) 字段截断 Guid 的尾随零

    在 C 中 我有一个byte 名为 UniqueId 的字段 我将此字段作为 Binary 16 存储在 SQL Server 数据库 EF6 中 我注意到有时 存储的 guid 是 15 个字节而不是 16 个字节 当我这样做时 这会导致
  • 从月份名称获取月份编号?

    快速问题 我有一个按名称列出的月份列表 即 Jan Feb Mar Apr 等 我想将其转换为 1 2 3 4 等 我已经写了一些简单的代码可以做到这一点 但只是好奇是否有人知道使用任何 API 来做到这一点的方法 快速回答 NSDateF
  • Memcached 使用超过最大内存

    我在 memcache 上安装了一个安装程序 我想在生产环境中使用它 但是当我运行了一些测试时 似乎 memcache 不会释放内存 即使它用完了所有分配的内存 我也登录了并运行了flush all命令 但对象仍在缓存中 这是一些测试的输出
  • 使用 CreateProcessAsUser 启动 url

    最近我遇到了一个问题 我需要从提升的应用程序打开网页 我需要以非提升方式打开浏览器 所以我环顾四周 发现这个解决方案 https stackoverflow com a 287072 127602 这肯定会解决我的问题 除了CreatePr
  • windows批处理文件eq此时出乎意料

    我正在编写一个 Windows 批处理脚本来安装服务 首先 我需要查找该服务是否已经存在 如果服务存在 它必须检查状态 如果状态正在运行 则必须停止并删除服务 这是我的代码 test bat 我正在从命令行运行它 for F tokens
  • 操作栏中的自定义主页图标 Sherlock

    我正在尝试使用设置主页图标的自定义图标ActionBarSherlock 库 http actionbarsherlock com 我尝试使用设置自定义布局abHomeLayout我的自定义主题中的属性 但这对我不起作用 唯一的方法 如何设
  • FieldValue.increment 不起作用,但添加“操作数”

    我正在使用 firebase 数据库和一个带有新功能的简单函数FieldValue increment https firebase google com docs reference js firebase firestore Field
  • 在 JavaScript 中执行继承

    现在 虽然我知道您不能像在 C 中那样执行继承 但我在互联网上看到它提到这是可能的 如果无法使用纯 JavaScript 代码 那么是否可以使用Ext JS http en wikipedia org wiki Ext JS如果是这样怎么办
  • 伊莎贝尔的文件准备

    我想获得与相关的 LaTeX 代码这个理论 https github com rjraya Isabelle blob master curves Hales thy 以前的答案仅提供文档的链接 让我描述一下我做了什么 我去了目录Hales
  • Eclipse PDT 插件安装

    我尝试在 Eclipse 中安装 PDT 插件 但出现错误 Cannot complete the install because one or more required items could not be found Software
  • Firebase 身份验证 - 过期的 api 密钥

    我正在开发一个无服务器客户端应用程序 它使用 Firebase 身份验证和 Google 的其他服务 一切都很顺利 突然 FB 登录身份验证停止工作 当尝试登录用户时 我会收到一个 400 BADREQUEST 其正文如下 error co
  • 使用 Socket.IO 发送数据的频率是多少?

    我正在创建一个 Web 应用程序 需要频繁地将少量数据 每个套接字 3 个整数值 从服务器发送到客户端 并且我想看看是否有使用更新客户端的最大频率套接字IO https socket io 我希望能够实现至少 50 个套接字连接 每个连接每