我已经使用WebSockets一段时间了,我选择使用Node服务器和WebSockets为我在大学的最后一年项目创建一个敏捷项目管理工具。我发现使用 WebSockets 使我的应用程序每秒可以处理的请求数量增加了 624%。
但是,自从启动该项目以来,我已经阅读了安全漏洞,并且某些浏览器选择默认禁用WebSockets。
这让我想到了一个问题:
当 WebSockets 似乎在降低延迟和资源开销方面做得如此出色时,为什么要使用 AJAX,AJAX 有什么比 WebSockets 做得更好的吗?
WebSockets 并不打算取代 AJAX,严格来说甚至不是 Comet/long-poll 的替代品(尽管在许多情况下这是有意义的(。
WebSockets 的目的是在浏览器和服务器之间提供低延迟、双向、全双工和长时间运行的连接。WebSockets 为浏览器应用程序开辟了新的应用程序域,而这些应用程序使用 HTTP 和 AJAX (交互式游戏、动态媒体流、桥接到现有网络协议等(是不可能实现的。
但是,WebSockets 和 AJAX/Comet 之间肯定存在目的重叠。例如,当浏览器希望收到服务器事件(即推送(的通知时,Comet 技术和 WebSockets 当然都是可行的选择。如果您的应用程序需要低延迟推送事件,那么这将是有利于 WebSocket 的一个因素。另一方面,如果您需要与现有框架和部署的技术(OAuth,RESTful API,代理,负载均衡器(共存,那么这将是支持Comet技术的一个因素(目前(。
如果你不需要WebSockets提供的特定好处,那么坚持使用现有的技术(如AJAX和Comet(可能是一个更好的主意,因为这允许您重用并与现有的工具,技术,安全机制,知识库的庞大生态系统集成(即stackoverflow上更多的人知道HTTP/Ajax/Comet而不是WebSockets(。 等。
另一方面,如果您正在创建一个在 HTTP/Ajax/Comet 的延迟和连接约束下无法正常工作的新应用程序,请考虑使用 WebSockets。
此外,一些答案表明 WebSockets 的缺点之一是有限/混合的服务器和浏览器支持。让我稍微分散一下。虽然iOS(iPhone,iPad(仍然支持较旧的协议(Hixie(,但大多数WebSockets服务器同时支持Hixie和HyBi/IETF 6455版本。大多数其他平台(如果它们还没有内置支持(可以通过web-socket-js(基于Flash的polyfill(获得WebSockets支持。这涵盖了绝大多数网络用户。此外,如果您将 Node 用于服务器后端,请考虑使用包含 web-socket-js 的 Socket.IO 作为回退,如果即使它不可用(或禁用(,那么它将回退到使用任何可用于给定浏览器的 Comet 技术。
更新:iOS 6 现在支持当前的 HyBi/IETF 6455 标准。
快进到 2017 年 12 月,(实际上(每个浏览器都支持 Websockets,并且它们的使用非常普遍。
然而,这并不意味着Websockets设法取代了AJAX,至少不是完全取代,特别是随着HTTP/2适应的增加。
简短的回答是,AJAX对于大多数REST应用程序来说仍然很棒,即使在使用Websockets时也是如此。但上帝在细节中,所以...:
用于轮询的 AJAX?
使用 AJAX 进行轮询(或长轮询(正在消亡(它应该消亡(,但它仍然在使用中有两个很好的原因(主要用于较小的 Web 应用程序(:
-
对于许多开发人员来说,AJAX 更容易编码,尤其是在编码和设计后端时。
-
使用 HTTP/2,消除了与 AJAX(建立新连接(相关的最高成本,使 AJAX 调用具有相当高的性能,尤其是在发布和上传数据时。
但是,Websocket 推送远远优于 AJAX(无需重新验证或重新发送标头,无需"无数据"往返等(。这个问题被讨论了很多次。
AJAX for REST?
AJAX 更好的用途是 REST API 调用。这种使用简化了代码库,并防止 Websocket 连接阻塞(尤其是在中型数据上传时(。
有许多令人信服的理由使 AJAX 更适合 REST API 调用和数据上传:
AJAX API 实际上是为 REST API 调用而设计的,它非常适合。
使用 AJAX 的 REST 调用和上传在客户端和后端都更容易编码。
随着数据有效负载的增加,除非对消息分段/多路复用逻辑进行编码,否则 Websocket 连接可能会被阻止。
如果在单个 Websocket
send
调用中执行上传,则可能会阻止 Websocket 流,直到上传完成。这将降低性能,尤其是在速度较慢的客户端上。
常见的设计使用通过 Websocket 传输的小双向消息,而 REST 和数据上传(客户端到服务器(利用 AJAX 的易用性来防止 Websocket 阻塞。
然而,在较大的项目中,Websockets提供的灵活性以及代码复杂性和资源管理之间的平衡将使平衡有利于Websockets。
例如,基于 Websocket 的上传可以提供在连接断开并重新建立后恢复大型上传的功能(还记得您要上传的 5GB 电影吗?
通过编码上传碎片逻辑,很容易恢复中断的上传(困难的部分是编码(。
HTTP/2推送呢?
我可能应该补充一点,HTTP/2推送功能不会(也可能不能(取代Websockets。
这在之前已经讨论过了,但只要提到单个HTTP/2连接服务于整个浏览器(所有选项卡/窗口(就足够了,因此由HTTP/2推送的数据不知道它属于哪个选项卡/窗口,从而消除了它取代Websocket将数据直接推送到特定浏览器选项卡/窗口的能力。
虽然Websockets非常适合小型双向数据通信,但AJAX仍然具有许多优势 - 特别是在考虑更大的有效载荷(上传等(时。
还有安全?
嗯,一般来说,提供给程序员的信任和控制越多,工具就越强大......以及更多的安全问题。
AJAX本质上会占上风,因为它的安全性内置于浏览器的代码中(有时这是有问题的,但它仍然存在(。
另一方面,AJAX 调用更容易受到"中间人"攻击,而 Websocket 安全问题通常是应用程序代码中的错误,引入了安全漏洞(通常后端身份验证逻辑是您可以找到这些错误的地方(。
就我个人而言,我不认为这有什么大区别,如果有的话,我认为 Websockets 稍微好一点,尤其是当你知道自己在做什么时。
我的拙见
恕我直言,我会将 Websockets 用于除 REST API 调用之外的所有内容。大数据上传 我会在可能的情况下分段并通过 Websocket 发送。
民意调查,恕我直言,应该被取缔,网络流量的成本是可怕的,即使对于新开发人员来说,Websocket 推送也很容易管理。
除了旧版浏览器(包括IE9,因为从IE10开始将支持WebSockets(的问题外,尚未支持WebSockets的网络中介仍然存在很大问题,包括透明代理,反向代理和负载平衡器。有一些移动运营商会完全阻止 WebSocket 流量(即在 HTTP UPGRADE 命令之后(。
随着岁月的流逝,WebSockets将得到越来越多的支持,但与此同时,您应该始终使用基于HTTP的回退方法来将数据发送到浏览器。
我读到的关于websockets和安全性的大多数抱怨都来自Web浏览器安全和防火墙安全工具的安全供应商。问题是他们不知道如何对websockets流量进行安全分析,因为一旦它完成了从HTTP到websocket二进制协议的升级,数据包内容及其含义是特定于应用程序的(基于您编程的任何内容(。对于这些公司来说,这显然是一场物流噩梦,他们的生计是基于分析和分类您的所有互联网流量。:)
WebSocket 在较旧的 Web 浏览器中不起作用,并且支持它的浏览器通常具有不同的实现。这几乎是为什么它们没有一直用来代替AJAX的唯一好理由。
我不认为我们可以对Websockets和HTTP进行清晰的比较,因为它们不是竞争对手,也不能解决相同的问题。
Websocket 是以近乎实时的方式处理长期双向数据流的绝佳选择,而 REST 非常适合偶尔的通信。使用 websockets 是一项相当大的投资,因此对于偶尔的连接来说,这是一种矫枉过正。
您可能会发现 Websocket 在存在高负载时做得更好,HTTP 在某些情况下略快,因为它可以利用缓存。将 REST 与 Websockets 进行比较就像将苹果与橙子进行比较。
我们应该检查哪一个为我们的应用程序提供更好的解决方案,哪一个最适合我们的用例获胜。
之间差异的一个示例,其形式为客户端大小的库,可以处理 Websocket 端点(如 REST API(和 RESTful 端点(如客户端上的 Websockets(。https://github.com/mikedeshazer/sockrest此外,对于那些尝试在客户端上使用 websocket API 的人,反之亦然。libs/sockrest.js几乎清楚地表明了差异(或者更确切地说是应该的(。