我已经使用WebSockets有一段时间了,我选择在大学最后一年的项目中使用Node服务器和WebSockets创建一个敏捷项目管理工具。我发现使用WebSockets使我的应用程序每秒可以处理的请求数量增加了624%。
然而,自从开始项目,我读到安全漏洞,和一些浏览器选择禁用WebSockets默认。
这让我想到一个问题:
既然WebSockets在降低延迟和资源开销方面做得如此出色,为什么还要使用AJAX呢? AJAX在哪些方面比WebSockets做得更好呢?
我已经使用WebSockets有一段时间了,我选择在大学最后一年的项目中使用Node服务器和WebSockets创建一个敏捷项目管理工具。我发现使用WebSockets使我的应用程序每秒可以处理的请求数量增加了624%。
然而,自从开始项目,我读到安全漏洞,和一些浏览器选择禁用WebSockets默认。
这让我想到一个问题:
既然WebSockets在降低延迟和资源开销方面做得如此出色,为什么还要使用AJAX呢? AJAX在哪些方面比WebSockets做得更好呢?
除了老式浏览器的问题(包括IE9,因为WebSockets将从IE10开始支持),网络中介还不支持WebSockets,包括透明代理、反向代理和负载平衡器,仍然存在很大的问题。 有一些移动运营商完全阻断WebSocket流量(即在HTTP UPGRADE命令之后)。
随着时间的推移,WebSockets将得到越来越多的支持,但与此同时,您应该始终有一个基于http的回退方法来将数据发送到浏览器。
WebSockets并不打算取代AJAX,甚至严格来说也不是Comet/long-poll的替代品(尽管在许多情况下这是有意义的)。
WebSockets的目的是在浏览器和服务器之间提供低延迟、双向、全双工和长时间运行的连接。WebSockets为浏览器应用程序打开了新的应用领域,这是使用HTTP和AJAX无法实现的(交互式游戏、动态媒体流、到现有网络协议的桥接等)。
However, there is certainly an overlap in purpose between WebSockets and AJAX/Comet. For example, when the browser wants to be notified of server events (i.e. push) then Comet techniques and WebSockets are certainly both viable options. If your application needs low-latency push events then this would be a factor in favor of WebSockets. On the other hand, if you need to co-exist with existing frameworks and deployed technologies (OAuth, RESTful APIs, proxies, load balancers) then this would be a factor in favor of Comet techniques (for now).
如果你不需要WebSockets提供的特定好处,那么坚持使用现有的技术,如AJAX和Comet,可能是一个更好的主意,因为这允许你重用和集成一个巨大的现有生态系统的工具,技术,安全机制,知识库(例如,stackoverflow上了解HTTP/ AJAX /Comet的人比WebSockets多得多),等等。
另一方面,如果您正在创建的新应用程序不能在HTTP/Ajax/Comet的延迟和连接限制内很好地工作,那么可以考虑使用WebSockets。
Also, some answers indicate that one of the downsides of WebSockets is limited/mixed server and browser support. Let me just diffuse that a bit. While iOS (iPhone, iPad) still supports the older protocol (Hixie) most WebSockets servers support both Hixie and the HyBi/IETF 6455 version. Most other platforms (if they don't already have built-in support) can get WebSockets support via web-socket-js (Flash based polyfill). This covers the vast majority of web users. Also, if you are using Node for the server backend, then consider using Socket.IO which includes web-socket-js as a fallback and if even that is not available (or disabled) then it will fall back to using whatever Comet technique is available for the given browser.
更新:iOS 6现在支持当前的HyBi/IETF 6455标准。
Most of the complaining I have read about websockets and security is from security vendors of web browser security and firewall security tools. The problem is they don't know how to do security analysis of websockets traffic, because once it has done the upgrade from HTTP to the websocket binary protocol, the packet content and its meaning is application specific (based on whatever you program). This is obviously a logistic nightmare for these companies whose livelihood is based on analyzing and classifying all your internet traffic. :)
快进到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连接阻塞(特别是在中等大小的数据上传时)。
在REST API调用和数据上传方面,有很多令人信服的理由选择AJAX:
AJAX API实际上是为REST API调用而设计的,非常适合。 使用AJAX的REST调用和上传在客户端和后端都非常容易编码。 随着数据有效负载的增加,Websocket连接可能会阻塞,除非对消息碎片/多路复用逻辑进行编码。 如果一个上传是在一个Websocket send调用中执行的,它会阻塞一个Websocket流,直到上传完成。这将降低性能,特别是在速度较慢的客户机上。
一个常见的设计是使用小的bidi消息通过Websocket传输,而REST和数据上传(客户端到服务器)利用AJAX的易用性来防止Websocket阻塞。
然而,在较大的项目中,Websockets所提供的灵活性以及代码复杂性和资源管理之间的平衡将使平衡向有利于Websockets的方向倾斜。
例如,基于Websocket的上传可以提供在断开连接并重新建立连接后恢复大型上传的能力(还记得您想要上传的5GB电影吗?)
通过编码上传碎片逻辑,可以很容易地恢复被中断的上传(困难的部分是编码)。
HTTP/2 push呢?
我应该补充一点,HTTP/2推送特性不会(也可能不能)取代Websockets。
这一点之前已经讨论过了,但值得一提的是,单个HTTP/2连接服务于整个浏览器(所有选项卡/窗口),因此通过HTTP/2推送的数据不知道它属于哪个选项卡/窗口,从而消除了它取代Websocket直接将数据推送到特定浏览器选项卡/窗口的能力。
虽然Websockets非常适合小型双向数据通信,但AJAX仍然具有许多优势——特别是在考虑更大的有效负载(上传等)时。
和安全吗?
一般来说,给予程序员的信任和控制越多,这个工具就越强大……安全隐患也越来越多。
AJAX在本质上是占上风的,因为它的安全性是内置在浏览器的代码中(这有时是值得怀疑的,但它仍然存在)。
另一方面,AJAX调用更容易受到“中间人”攻击,而Websockets安全问题通常是应用程序代码中引入安全缺陷的bug(通常后端身份验证逻辑就是这些漏洞的来源)。
就我个人而言,我不认为这有什么大的不同,如果有的话,我认为Websockets稍微好一点,特别是当你知道你在做什么时。
我的拙见
恕我直言,除了REST API调用,我什么都用Websockets。如果可能的话,我会将大数据上传碎片化并通过Websockets发送。
恕我直言,轮询应该是非法的,网络流量的成本是可怕的,Websocket推送甚至对新开发人员来说也很容易管理。
我不认为我们可以对Websockets和HTTP做一个清晰的比较,因为它们不是竞争对手,也解决不了同样的问题。
Websockets是一个很好的选择,可以以接近实时的方式处理长时间的双向数据流,而REST则适合偶尔的通信。使用websockets是一项相当大的投资,因此它对于偶尔的连接来说是一种过度的使用。
你可能会发现Websockets在高负载时做得更好,HTTP在某些情况下稍微快一点,因为它可以利用缓存。比较REST和Websockets就像比较苹果和橘子。
我们应该检查哪个为我们的应用程序提供了更好的解决方案,哪个最适合我们的用例胜出。
HTTP和Websockets之间的区别的一个例子,它是一个客户端大小的库,可以处理Websocket端点(如REST api)和客户端上的Websockets端点(如Websockets)。 https://github.com/mikedeshazer/sockrest 此外,对于那些试图在客户端使用websocket API的人,或者相反,他们习惯的方式。libs/sockrest.js很清楚地说明了这些区别(或者应该是这样)。