【问题标题】:nodejs: Ajax vs Socket.IO, pros and consnodejs:Ajax 与 Socket.IO,优缺点
【发布时间】:2011-11-03 19:34:36
【问题描述】:

我曾想过摆脱所有客户端 Ajax 调用 (jQuery),而使用永久套接字连接 (Socket.IO)。

因此我会在客户端和服务器端使用事件监听器/发射器。

例如。用户在浏览器中触发点击事件,客户端发射器通过套接字连接将事件推送到服务器。服务器端侦听器对传入事件做出反应,并将“完成”事件推回客户端。客户端的侦听器通过淡入 DIV 元素对传入事件做出反应。

这有意义吗? 利弊?

【问题讨论】:

标签: ajax jquery node.js socket.io


【解决方案1】:

这个帖子中有很多非常不准确的常见错误信息。

TL/DR; WebSocket 替换应用程序的 HTTP!它是由谷歌在微软和许多其他领先公司的帮助下设计的。所有浏览器都支持它。 没有缺点。

SocketIO 建立在 WebSocket 协议 (RFC 6455) 之上。它旨在完全替换 AJAX。它没有任何可扩展性问题。它比 AJAX 运行速度更快,同时消耗的资源少一个数量级。

AJAX 已有 10 年历史,它建立在单个 JavaScript XMLHTTPRequest 函数之上,该函数被添加以允许在不重新加载整个页面的情况下回调服务器。

换句话说,AJAX 是一种文档协议 (HTTP),只有一个 JavaScript 函数。

相比之下,WebSocket 是一种应用程序协议,旨在完全取代 HTTP。当您升级 HTTP 连接(通过请求 WebSocket 协议)时,您启用了与服务器的双向全双工通信,并且不涉及任何协议握手。使用 AJAX,您要么必须启用 keep-alive(与 SocketIO 相同,只是旧协议),要么在每次发出 AJAX 请求时强制执行新的 HTTP 握手,这会使服务器陷入瘫痪。

运行在 Node 之上的 SocketIO 服务器可以在保持活动模式下处理 100,000 个并发连接,仅使用 4gb 内存和单个 CPU,这个限制是由 V8 垃圾收集引擎造成的,不是协议。即使在您最疯狂的梦想中,您也永远不会使用 AJAX 实现这一目标。

为什么 SocketIO 速度如此之快,消耗的资源却如此之少

再次出现这种情况的主要原因是,WebSocket 为应用程序设计,而 AJAX 是一种在文档协议之上启用应用程序的变通方法。

如果您深入研究 HTTP 协议并使用 MVC 框架,您会发现单个 AJAX 请求实际上会将 700-900 字节的协议负载传输到 AJAX 到一个 URL(没有您自己的任何有效负载)。与之形成鲜明对比的是,WebSocket 使用大约 10 个字节,或大约 70 倍的数据来与服务器通信。

由于 SocketIO 保持开放连接,因此无需握手,服务器响应时间仅限于往返或 ping 服务器本身的时间。

socket连接是port连接的错误信息;它不是。套接字连接只是表中的一个条目。消耗的资源很少,单台服务器可以提供 1,000,000+ 个 WebSocket 连接。 AWS XXL 服务器可以并且确实托管 1,000,000 多个 SocketIO 连接。

AJAX 连接将 gzip/deflate 整个 HTTP 标头、解码标头、编码标头并启动 HTTP 服务器线程来处理请求,因为这是一个文档协议;服务器被设计为一次性吐出文档。

相比之下,WebSocket 只是在表中为连接存储一个条目,大约 40-80 个字节。字面意思就是这样。根本不进行轮询。

WebSocket 设计可扩展。

至于 SocketIO 很乱……根本不是这样的。 AJAX 很乱,你需要 promise/response。

使用 SocketIO,您只需拥有发射器和接收器;他们甚至不需要了解彼此;不需要承诺系统:

要请求用户列表,您只需向服务器发送一条消息...

socket.emit("giveMeTheUsers");

当服务器准备就绪时,它会向您发送另一条消息。塔达,你完成了。因此,要处理用户列表,您只需说出在收到您正在寻找的响应时要做什么...

socket.on("HereAreTheUsers", showUsers(data) );

就是这样。哪里乱了?好吧,没有:) 关注点分离?为你做了。锁定客户,让他们知道他们必须等待?他们不必等待 :) 您可以随时获得新的用户列表...服务器甚至可以通过这种方式回放任何 UI 命令...客户端可以连接到 每个其他甚至不使用带有 WebRTC 的服务器...

SocketIO 中的聊天系统? 10 行代码。实时视频会议? 80 行代码 是的……Luke……加入我。为工作使用正确的协议...如果您正在编写应用程序...使用应用程序协议。

我认为这里的问题和困惑来自那些习惯于使用 AJAX 并且认为他们需要客户端上所有额外的 Promise 协议和后端上的 REST API 的人......好吧,你没有。 :) 不再需要了 :)

是的,您没看错……当您决定切换到 WebSocket 时,不再需要 REST API。 REST 实际上已经过时了。如果您编写桌面应用程序,您是否使用 REST 与对话框进行通信?不 :) 这很愚蠢。

SocketIO,利用 WebSocket 为您做同样的事情......您可以开始将客户端视为您应用程序的简单对话框。您根本不再需要 REST。

事实上,如果你在使用 WebSocket 的同时尝试使用 REST,那就像使用 REST 作为桌面对话框的通信协议一样愚蠢……完全没有意义。

你说蒂米是什么意思?想要使用您的应用程序的其他应用程序呢?你应该让他们访问 REST 吗? Timmy...WebSocket 已经推出 4 年了...只需让他们使用 WebSocket 连接到您的应用程序,并让他们使用 that 协议请求消息...它将消耗 50 倍的资源,速度更快,开发更容易 10 倍...为什么要在创造未来时支持过去?

当然,有 REST 的用例,但它们都适用于旧的和过时的系统......大多数人还不知道。

更新:

很多人最近一直在问我,他们如何才能在 2018 年(现在很快 2019 年)开始使用 WebSockets 编写应用程序,一旦他们使用 Sockets,障碍似乎真的很高.IO 他们不知道还能去哪里学习或学习什么。

幸运的是,过去 3 年对 WebSockets 非常友好......

现在有 3 个主要框架支持BOTH REST 和 WebSocket,甚至物联网协议或其他最小/快速协议,如 ZeroMQ,您不必担心任何这些;您只需开箱即用即可获得支持。

注意: 虽然 Meteor 是目前最流行的,但我将其排除在外,因为尽管它们是一个非常非常有资金的 WebSocket 框架,但任何使用 Meteor 编码多年的人会告诉你,这是一个内部混乱和规模的噩梦。有点像 WordPress 之于 PHP,它就在那里,它很流行,但它的制作不是很好。没有经过深思熟虑,很快就会死去。对不起 Meteor 的人,但是看看这 3 个与 Meteor 相比的其他项目,你会在同一天扔掉 Meteor :)

使用以下所有框架,您只需编写一次服务,即可获得 REST 和 WebSocket 支持。更重要的是,只需一行配置代码即可在几乎任何后端数据库之间进行交换。

Feathers 最容易使用,在前端和后端工作相同,并且支持大多数功能,Feathers 是用于现有工具(如 express)的轻量级包装器的集合。使用像 feathers-vuex 这样很棒的工具,您可以创建完全可模拟的不可变服务,支持 REST、WebSocket 和其他协议(使用 Primus),并获得免费的完整 CRUD 操作,包括搜索和分页,而无需一行代码(只需一些配置)。对于生成的数据(如json-schema-faker)也非常有效,因此您不仅可以完全模拟事物,还可以使用随机但有效的数据模拟它。您可以连接应用程序以支持预先输入搜索、创建、删除和编辑,而 无需代码(只需配置)。你们中的一些人可能知道,正确的代码通过配置是自我修改代码的最大障碍。 Feathers 做得对,并将在未来的应用设计中将您推向最前沿。

Moleculer 不幸的是,Moleculer 在后端比 Feathers 好一个数量级。虽然羽毛可以工作,并且可以让您扩展到无限,但羽毛甚至根本没有开始考虑诸如生产集群、实时服务器控制台、容错、开箱即用的管道日志或 API 网关之类的事情(虽然我已经构建了一个来自 Feathers 的生产 API 网关,Moleculer 做得更好)。与任何 WebSocket 框架相比,Moleculer 在流行度和新功能方面也是增长最快的。

Moleculer 的成功之处在于您可以将 Feathers 或 ActionHero 前端与 Moleculer 后端结合使用,尽管您失去了一些生成器,但您获得了很多生产质量。

因此,我建议在前端和后端学习 Feathers,一旦您制作了第一个应用程序,请尝试将后端切换到 Moleculer。 Moleculer 更难上手,但这仅仅是因为它为您解决了所有的缩放问题,而这些信息可能会使新用户感到困惑。

ActionHero 在此列出作为可行的替代方案,但 Feathers 和 Moleculer 是更好的实现。如果关于 ActionHero 的任何内容不适合您,请不要使用它;上面有两种更好的方法可以为您提供更多、更快的服务。

注意: API 网关是未来,以上所有 3 个都支持它们,但 Moleculer 确实为您提供了开箱即用的功能。 API 网关让您可以处理客户端交互,允许缓存、记忆、客户端到客户端消息传递、黑名单、注册、容错和所有其他扩展问题由单个平台组件处理。将您的 API 网关与 Kubernetes 相结合,可以让您以尽可能少的问题扩展到无限。它是可扩展应用程序可用的最佳设计方法。

2021 年更新

行业发展如此之快,您甚至无需关注协议。 GraphQL 现在默认使用 WebSockets!只需查看如何使用订阅,就完成了。处理它的最快方法将为您提供。

如果您使用 Vue、React 或 Angular,那么您很幸运,因为有适合您的原生 GraphQL 实现!只需使用 GraphQL 订阅从服务器调用您的数据,该数据对象将保持最新状态并自行响应

当您需要使用旧系统时,GraphQL 甚至会为您回退到 REST,并且订阅仍将使用套接字进行更新。迁移到 GraphQL 后,一切都迎刃而解。

是的,如果您认为“WTH?!?”当您听说您可以像使用 FireBase 一样简单地订阅服务器对象时,它会自动为您更新。是的。现在是真的。只需使用 GraphQL 订阅。它将使用 WebSockets。

聊天系统? 1行代码。 实时视频系统? 1行代码。 100 万实时用户共享 10mb 开放世界数据的视频游戏? 1行代码。该代码现在只是您的 GQL 查询。

只要您构建或使用正确的后端,所有这些实时工作现在都可以通过 GQL 订阅为您完成。尽快做出改变,不要再担心协议了。

【讨论】:

  • 你提到的很多关于 ajax 的陷阱都可以用http2.github.io解决
  • @NickSteele 是一篇旧帖子,但感谢您提供有关 socket.io 的精彩而全面的信息。你能帮我理解 socket.io 中的 HEARTBEAT 实现是做什么的以及如何使用它吗?我正在向我的同事提出一些建议,我知道他们会提出一件事,因为潜在的问题是“失去联系怎么办”?
  • @Hassek 感谢您的评论并指出...我会尽量表现得好像我将来已经进入青春期。
  • 你答案的最后一部分是金。我爱提米。信息量很大。干得好。
  • 惊人的答案。这澄清了大多数人的许多担忧。您对技术的热情体现在您的回答中:)
【解决方案2】:

发送单向消息并对其调用回调可能会变得非常混乱。

$.get('/api', sendData, returnFunction);socket.emit('sendApi', sendData);socket.on('receiveApi', returnFunction);

这就是为什么 dnode 和 nowjs 建立在 socket.io 之上以使事情变得易于管理的原因。仍然是事件驱动,但没有放弃回调。

【讨论】:

  • 非常感谢,nowjs 正是我想要的,我喜欢这个新世界。有任何安全问题吗?
  • websockets 协议存在一些小的安全问题(没有漏洞,但已知弱点),它们正在被整理出来。如果有任何漏洞,您可以简单地关闭 websockets。
  • 这个答案类似于说灯泡很乱,因为当您尝试点亮它们时,它们会产生碳痕并最终破裂并爆裂,因此您应该坚持用火。你这样做是错的。事件首先不需要回调 :) 您使用的是正确的技术(事件)和错误的范例(回调)。事件让您简单地拨打电话(不支持)。对于你提出请求的事件,你作出声明。你不是在要求什么,你只是在说发生了什么。 socket.emit('clickedLogin')。然后当登录工作时,Node 发送 socket.emit('loadApp')。砰,完成。
  • 通过socket.io,它提供回调socket.emit('sendApi', sendData, returnFunction)
【解决方案3】:

Socket.IO 使用客户端和服务器之间的持久连接,因此您将达到最大并发连接数限制,具体取决于您在服务器端拥有的资源,而更多的 Ajax 异步请求可以使用相同的资源提供服务。

Socket.IO 主要是为客户端和服务器之间的实时和双向连接而设计的,在某些应用程序中不需要保持永久连接。另一方面,Ajax 异步连接应该通过 HTTP 连接设置阶段并随每个请求发送标头数据和所有 cookie。

Socket.IO 被设计为单进程服务器,可能存在可伸缩性问题,具体取决于您绑定到的服务器资源。

Socket.IO 不太适合用于缓存客户端请求结果的应用程序。

Socket.IO 应用程序在 SEO 优化和搜索引擎索引方面面临困难。

Socket.IO 不是标准也不等同于 W3C Web Socket API,如果浏览器支持,它使用当前的 Web Socket API,socket.io 是一个人创建的,用于解决实时应用程序中的跨浏览器兼容性,还很年轻,大约1岁。与 ajax/jquery 相比,它的学习曲线、更少的开发人员和社区资源、长期维护以及更少的需求或未来更好的选择对于开发团队是否基于 socket.io 编写代码可能很重要。

【讨论】:

  • 这里有一些优点,除了最后两个。 SEO 问题适用于基于 Ajax 的网站与使用 Web 套接字的网站一样。 Socket.io 将在可用的情况下使用浏览器的 W3C Web Socket 实现,并且仅在不可用时回退到其他方法。
  • 一个优点是并发连接数有限,SEO 已成为历史 - code.google.com/web/ajaxcrawling/docs/getting-started.html
  • @ezmilhouse - 你是什么意思?历史如何?
  • 这完全关闭了。使用 Ajax,您可以为每个请求启动 1 个线程。使用 WebSocket,您可以将 1 个对象添加到数组中……基本连接大约需要 80 个字节。这意味着,如果您有一个最小的应用程序,您可以在单个服务器上连接大约 100 万用户和大约 80mb 的数据,在一个线程中,这意味着所有用户都可以在同一个线程中交换消息......这是很多数量级有效。地球上没有办法在单个服务器上支持 100 万个 ajax 请求,更不用说单个线程了 :)
  • 如果你使用谷歌云应用引擎,服务器上的用户数不会成为问题,因为资源被占用时会自动创建一个新的服务器实例。
猜你喜欢
  • 2011-08-19
  • 1970-01-01
  • 2016-10-29
  • 2023-04-04
  • 2011-01-26
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多