这个帖子中有很多非常不准确的常见错误信息。
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 订阅为您完成。尽快做出改变,不要再担心协议了。