Web套接字使ajax / CORS过时了吗?

时间:2010-10-28 12:02:52

标签: ajax websocket cors

在所有Web浏览器中使用Web套接字会使ajax过时吗?

如果我可以使用网络套接字实时获取数据和更新数据,为什么我需要ajax?即使我在应用程序启动时使用ajax只获取一次数据,我仍然可能想看看这段数据是否在一段时间后发生了变化。

网络套接字是可以在跨域还是只能到同一个来源?

4 个答案:

答案 0 :(得分:79)

WebSockets不会使AJAX完全过时,WebSockets也可以跨域。

AJAX

AJAX机制可以与普通的Web服务器一起使用。在最基本的层面上,AJAX只是网页发出HTTP请求的一种方式。 WebSockets是一种更低级别的协议,需要一个WebSockets服务器(内置于Web服务器,独立或从Web服务器代理到独立服务器)。

使用WebSockets,框架和有效负载由应用程序确定。您可以在客户端和服务器之间来回发送HTML / XML / JSON,但您不必被迫。 AJAX是HTTP 。 WebSockets具有HTTP友好握手,但 WebSockets不是HTTP 。 WebSockets是一种双向协议,它比原始套接字(故意这样)更接近于HTTP。 WebSockets有效负载数据在标准的当前版本中以UTF-8编码,但在将来的版本中可能会更改/扩展。

因此,即使在所有客户端本身都支持WebSockets的世界中,也可能始终存在AJAX类型请求的位置。 WebSockets正试图解决AJAX不具备能力或能力不足的情况(因为WebSockets的双向性和低得多的开销)。但是WebSockets并不能取代AJAX所用的一切。

跨域

,WebSockets支持跨域。设置连接的初始握手通信源策略信息。维基百科页面显示了典型握手的示例:http://en.wikipedia.org/wiki/WebSockets

答案 1 :(得分:15)

我会尝试将其分解为问题:

  

在所有Web浏览器中使用Web套接字会使ajax过时吗?

绝对不是。 WebSockets是到服务器的原始套接字连接。这附带it's own security concerns。 AJAX调用只是异步。 HTTP请求可以遵循与其余页面相同的验证过程。

  

如果我可以使用网络套接字实时获取数据和更新数据,为什么我需要ajax?

您可以使用AJAX来实现更简单,更易于管理的任务。并非所有人都希望获得保护套接字连接的开销以简单地允许异步请求。这可以简单地处理。

  

即使我在应用程序启动时使用ajax只获取一次数据,我仍然可能想看看这段数据是否在一段时间后发生了变化。

当然,如果数据正在发生变化。您可能没有更改数据或不断更新数据。同样,这是您必须考虑的代码开销

  

网络套接字是可以在跨域还是只能到同一个来源?

您可以拥有跨域WebSockets,但必须对WS服务器进行编码才能接受它们。您可以访问域(主机)标头,然后可以使用该标头接受/拒绝请求。但是,这可以通过nc这样简单的事情来欺骗。为了真正保护连接,您需要通过其他方式验证连接。

答案 2 :(得分:10)

Websockets在可扩展性方面有一些很大的缺点,这是ajax避免的。由于ajax发送请求/响应并关闭连接(如果之后不久),如果有人留在网页上,则在空闲时它不会使用服务器资源。 Websockets用于将数据流回浏览器,并且它们会占用服务器资源。服务器在一次可以保持打开的同时连接数量方面存在限制。更不用说取决于您的服务器端技术,他们可能会绑定一个线程来处理套接字。因此,websockets对每个连接的双方都有更多的资源密集型要求。您可以轻松耗尽为客户端服务的所有线程,如果很多用户只是坐在页面上,则不会有新客户端进入。这就是nodejs,vertx,netty可以真正帮助的地方,但即便是那些也有上限。

还存在底层套接字状态的问题,并且在双方编写代码进行有状态对话,这与ajax风格无关,因为它是无状态的。 Websockets需要您创建一个低级协议,使用ajax为您解决。心脏跳动,关闭空闲连接,重新连接错误等等现在至关重要。这些是你在使用AJAX时不必解决的问题,因为它是无状态的。状态对于应用程序的稳定性非常重要,更重要的是服务器的运行状况。这不是微不足道的。在HTTP之前,我们构建了许多有状态的TCP协议(FTP,telnet,SSH),然后发生了HTTP。并且没有人再那样做了,因为即使有其局限性,HTTP也更加容易和强大。 Websockets带回了有状态协议的好坏。如果你没有得到最后一剂的剂量,你很快就会学到很多。

如果您需要实时数据流,这需要额外的开销,因为轮询服务器以获取流数据更糟糕,但如果您所做的只是用户交互 - >请求 - >响应 - >更新UI,那么ajax更容易并且将使用更少的资源,因为一旦发送响应,会话就结束了,并且不使用额外的服务器资源。所以我认为这是一种权衡,架构师必须决定哪种工具适合他们的问题。 AJAX占有一席之地,而websockets也占有一席之地。

<强>更新

因此,当我们讨论线程时,服务器的体系结构才是最重要的。如果您使用传统的多线程服务器(或进程),其中每个套接字连接都有自己的线程来响应请求,那么websockets对您很重要。因此,对于每个连接,我们都有一个套接字,如果你有太多的这些,最终操作系统将会崩溃,而线程也是如此(对于进程来说更是如此)。线程比套接字重(在资源方面),所以我们尝试保存我们同时运行的线程数。这意味着创建一个线程池,它只是在所有套接字之间共享的固定数量的线程。但是一旦打开套接字,该线程就会用于整个会话。这些对话的长度决定了你为这些新套接字重新调整这些线程的速度。你的会话长度决定了你可以扩展多少。但是,如果您正在流式传输此模型,则无法正常进行缩放。你必须打破线程/套接字设计。

HTTP的请求/响应模型使得在为新套接字转换线程时非常有效。如果您要使用请求/响应,请使用已构建的HTTP,并且比在websockets中重新实现类似的内容要容易得多。

由于websockets不必作为HTTP进行请求/响应,并且如果您的服务器在其线程池中具有固定数量的线程并且您具有相同数量的websockets来捆绑所有线程,则可以流式传输数据积极的对话,您无法为新客户提供服务!您已达到最大容量。协议设计对于websockets和线程来说也很重要。您的协议可能允许您放松每个会话模型的每个插槽的线程,这样人们只是坐在那里不会在您的服务器上使用线程。

异步单线程服务器进入的地方。在Java中,我们经常将此NIO称为非阻塞IO。这意味着它是套接字的不同API,其中发送和接收数据不会阻止执行调用的线程。

在调用socket.read()或socket.write()时阻塞套接字是如此传统,它们会等到收到或发送数据后再将控制权返回给程序。这意味着您的程序将等待套接字数据进入或退出,直到您可以执行任何其他操作为止。这就是为什么我们有线程所以我们可以同时工作(同时)。当我等待来自客户端Y的数据时,将此数据发送到客户端X.当谈论服务器时,Concurrencies是游戏的名称。

在NIO服务器中,我们使用单个线程来处理所有客户端并注册回调以在数据到达时得到通知。例如

socket.read( function( data ) {
   // data is here! Now you can process it very quickly without waiting!
});

socket.read()调用将立即返回而不读取任何数据,但是我们提供的函数将在调用时被调用。这种设计从根本上改变了构建和构建代码的方式,因为如果你等待挂起你无法接收任何新客户的东西。你有一个线程,你可以一次做两件事!你必须保持一个线程移动。

NIO,异步IO,基于事件的程序,因为这是众所周知的,是一个复杂得多的系统设计,如果你刚开始的话,我建议你不要试着写这个。即使是非常高级的程序员也很难建立一个强大的系统。由于您是异步的,因此无法调用阻止的API。就像从数据库中读取数据或向其他服务器发送消息一样,必须异步执行。即使从文件系统读取/写入也会降低单线程速度,从而降低可伸缩性。一旦你去异步,如果你想保持单个线程的移动,它就会一直异步。这就是挑战,因为最终你会遇到像DB一样的API,这不是异步的,你必须在某种程度上采用更多的线程。因此,即使在异步世界中,混合方法也很常见。

好消息是有其他解决方案使用已经构建的可以使用的低级API。 NodeJS,Vertx,Netty,Apache Mina,Play Framework,Twisted Python,Stackless Python等。可能有一些不为人知的C ++库,但说实话,我不会烦恼。服务器技术并不需要最快的语言,因为它的IO限制超过CPU限制。如果你是一个死硬的性能坚果使用Java。它拥有庞大的代码社区,它的速度与C ++相比非常接近(有时甚至更好)。如果你讨厌它,请使用Node或Python。

答案 3 :(得分:-13)

是的,是的。 :d

早期的答案缺乏想象力。如果你可以使用websockets,我认为没有理由使用AJAX。