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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4042691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:55:30  来源:igfitidea点击:

Web sockets make ajax/CORS obsolete?

ajaxwebsocketcors

提问by ajsie

Will web sockets when used in all web browsers make ajax obsolete?

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

Cause if I could use web sockets to fetch data and update data in realtime, why would I need ajax? Even if I use ajax to just fetch data once when the application started I still might want to see if this data has changed after a while.

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

And will web sockets be possible in cross-domains or only to the same origin?

网络套接字是否可以跨域或仅用于同一来源?

回答by kanaka

WebSockets will not make AJAX entirely obsolete and WebSockets can do cross-domain.

WebSockets 不会让 AJAX 完全过时,而且 WebSockets 可以跨域。

AJAX

AJAX

AJAX mechanisms can be used with plain web servers. At its most basic level, AJAX is just a way for a web page to make an HTTP request. WebSockets is a much lower level protocol and requires a WebSockets server (either built into the webserver, standalone, or proxied from the webserver to a standalone server).

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

With WebSockets, the framing and payload is determined by the application. You could send HTML/XML/JSON back and forth between client and server, but you aren't forced to. AJAX is HTTP. WebSockets has a HTTP friendly handshake, but WebSockets is not HTTP. WebSockets is a bi-directional protocol that is closer to raw sockets (intentionally so) than it is to HTTP. The WebSockets payload data is UTF-8 encoded in the current version of the standard but this is likely to be changed/extended in future versions.

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

So there will probably always be a place for AJAX type requests even in a world where all clients support WebSockets natively. WebSockets is trying to solve situations where AJAX is not capable or marginally capable (because WebSockets its bi-directional and much lower overhead). But WebSockets does not replace everything AJAX is used for.

因此,即使在所有客户端都原生支持 WebSockets 的世界中,AJAX 类型的请求也可能总有一席之地。WebSockets 试图解决 AJAX 没有能力或能力有限的情况(因为 WebSockets 是双向的且开销低得多)。但是 WebSockets 并不能取代 AJAX 的所有用途。

Cross-Domain

跨域

Yes, WebSockets supports cross-domain. The initial handshake to setup the connection communicates origin policy information. The wikipedia page shows an example of a typical handshake: http://en.wikipedia.org/wiki/WebSockets

是的,WebSockets 支持跨域。建立连接的初始握手传达源策略信息。维基百科页面显示了一个典型的握手示例:http: //en.wikipedia.org/wiki/WebSockets

回答by Josh K

I'll try to break this down into questions:

我会试着把它分解成几个问题:

Will web sockets when used in all web browsers make ajax obsolete?

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

Absolutely not. WebSockets are raw socket connections to the server. This comes with it's own security concerns. AJAX calls are simply async. HTTP requests that can follow the same validation procedures as the rest of the pages.

绝对不。WebSockets 是到服务器的原始套接字连接。这伴随着它自己的安全问题。AJAX 调用只是异步的。可以遵循与其余页面相同的验证程序的 HTTP 请求。

Cause if I could use web sockets to fetch data and update data in realtime, why would I need ajax?

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

You would use AJAX for simpler more manageable tasks. Not everyone wants to have the overhead of securing a socket connection to simply allow async requests. That can be handled simply enough.

您可以将 AJAX 用于更简单、更易于管理的任务。不是每个人都希望拥有保护套接字连接的开销以简单地允许异步请求。这可以很简单地处理。

Even if I use ajax to just fetch data once when the application started I still might want to see if this data has changed after a while.

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

Sure, if that data is changing. You may not have the data changing or constantly refreshing. Again, this is code overheadthat you have to account for.

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

And will web sockets be possible in cross-domains or only to the same origin?

网络套接字是否可以跨域或仅用于同一来源?

You can have cross domain WebSockets but you have to code your WS server to accept them. You have access to the domain (host) header which you can then use to accept / deny requests. This can, however, be spoofed by something as simple as nc. In order to truly secure the connection you will need to authenticate the connection by other means.

您可以拥有跨域 WebSockets,但您必须编写您的 WS 服务器以接受它们。您可以访问域(主机)标头,然后可以使用它来接受/拒绝请求。但是,这可能会被诸如nc. 为了真正确保连接安全,您需要通过其他方式验证连接。

回答by chubbsondubs

Websockets have a couple of big downsides in terms of scalability that ajax avoids. Since ajax sends a request/response and closes the connection (..or shortly after) if someone stays on the web page it doesn't use server resources when idling. Websockets are meant to stream data back to the browser, and they tie up server resources to do so. Servers have a limit in how many simultaneous connections they can keep open at one time. Not to mention depending on your server side technology, they may tie up a thread to handle the socket. So websockets have more resource intensive requirements for both sides per connection. You could easily exhaust all of your threads servicing clients and then no new clients could come in if lots of users are just sitting on the page. This is where nodejs, vertx, netty can really help out, but even those have upper limits as well.

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

Also there is the issue of state of the underlying socket, and writing the code on both sides that carry on the stateful conversation which isn't something you have to do with ajax style because it's stateless. Websockets require you create a low level protocol which is solved for you with ajax. Things like heart beating, closing idle connections, reconnection on errors, etc are vitally important now. These are things you didn't have to solve when using AJAX because it was stateless. State is very important to the stability of your app and more importantly the health of your server. It's not trivial. Pre-HTTP we built a lot of stateful TCP protocols (FTP, telnet, SSH), and then HTTP happened. And no one did that stuff much anymore because even with its limitations HTTP was surprisingly easier and more robust. Websockets bring back the good and the bad of stateful protocols. You'll learn soon enough if you didn't get a dose of that last go around.

还有底层套接字的状态问题,在双方编写进行有状态对话的代码,这与 ajax 风格无关,因为它是无状态的。Websockets 要求您创建一个低级协议,该协议使用 ajax 为您解决。诸如心跳、关闭空闲连接、错误时重新连接等之类的事情现在至关重要。这些是您在使用 AJAX 时不必解决的问题,因为它是无状态的。状态对您的应用程序的稳定性非常重要,更重要的是您的服务器的健康状况。这不是微不足道的。在 HTTP 之前,我们构建了很多有状态的 TCP 协议(​​FTP、telnet、SSH),然后 HTTP 发生了。没有人再做这些事情了,因为即使有它的限制,HTTP 也出奇地更简单、更健壮。Websockets 带回了有状态协议的优点和缺点。如果你最后一次没有得到一剂,你很快就会学会。

If you need streaming of realtime data this extra overhead is warranted because polling the server to get streamed data is worse, but if all you are doing is user interaction->request->response->update UI, then ajax is easier and will use less resources because once the response is sent the conversation is over and no additional server resources are used. So I think it's a tradeoff and the architect has to decide which tool fits their problem. AJAX has its place, and websockets have their place.

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

Update

更新

So the architecture of your server is what matters when we are talking about threads. If you are using a traditionally multi-threaded server (or processes) where a each socket connection gets its own thread to respond to requests then websockets matter a lot to you. So for each connection we have a socket, and eventually the OS will fall over if you have too many of these, and the same goes for threads (more so for processes). Threads are heavier than sockets (in terms of resources) so we try and conserve how many threads we have running simultaneously. That means creating a thread pool which is just a fixed number of threads that is shared among all sockets. But once a socket is opened the thread is used for the entire conversation. The length of those conversations govern how quickly you can repurpose those threads for new sockets coming in. The length of your conversation governs how much you can scale. However if you are streaming this model doesn't work well for scaling. You have to break the thread/socket design.

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

HTTP's request/response model makes it very efficient in turning over threads for new sockets. If you are just going to use request/response use HTTP its already built and much easier than reimplementing something like that in websockets.

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

Since websockets don't have to be request/response as HTTP and can stream data if your server has a fixed number of threads in its thread pool and you have the same number of websockets tying up all of your threads with active conversations, you can't service new clients coming in! You've reached your maximum capacity. That's where protocol design is important too with websockets and threads. Your protocol might allow you to loosen the thread per socket per conversation model that way people just sitting there don't use a thread on your server.

由于 websockets 不必像 HTTP 一样请求/响应并且可以流式传输数据,如果您的服务器在其线程池中有固定数量的线程并且您有相同数量的 websockets 将所有线程与活动对话捆绑在一起,您可以'不服务新客户进来!您已达到最大容量。这就是协议设计对于 websockets 和线程也很重要的地方。您的协议可能允许您放松每个会话模型每个套接字的线程,这样坐在那里的人就不会使用您服务器上的线程。

That's where asynchronous single thread servers come in. In Java we often call this NIO for non-blocking IO. That means it's a different API for sockets where sending and receiving data doesn't block the thread performing the call.

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

So traditional in blocking sockets when you call socket.read() or socket.write() they wait until the data is received or sent before returning control to your program. That means your program is stuck waiting for the socket data to come in or go out until you can do anything else. That's why we have threads so we can do work concurrently (at the same time). Send this data to client X while I wait on data from client Y. Concurrencies is the name of the game when we talk about servers.

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

In a NIO server we use a single thread to handle all clients and register callbacks to be notified when data arrives. For example

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

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

The socket.read() call will return immediately without reading any data, but our function we provided will be called when it comes in. This design radically changes how you build and architect your code because if you get hung up waiting on something you can't receive any new clients. You have a single thread you can't really do two things at once! You have to keep that one thread moving.

socket.read() 调用将在不读取任何数据的情况下立即返回,但是我们提供的函数将在它进入时被调用。这种设计从根本上改变了您构建和架构代码的方式,因为如果您挂断了等待某些事情,您可以'不接待任何新客户。你只有一个线程,你真的不能同时做两件事!你必须保持那个线程移动。

NIO, Asynchronous IO, Event based program as this is all known as, is a much more complicated system design, and I wouldn't suggest you try and write this if you are starting out. Even very Senior programmers find it very hard to build a robust systems. Since you are asynchronous you can't call APIs that block. Like reading data from the DB or sending messages to other servers have to be performed asynchronously. Even reading/writing from the file system can slow your single thread down lowering your scalability. Once you go asynchronous it's all asynchronous all the time if you want to keep the single thread moving. That's where it gets challenging because eventually you'll run into an API, like DBs, that is not asynchronous and you have to adopt more threads at some level. So a hybrid approaches are common even in the asynchronous world.

NIO,异步 IO,基于事件的程序,众所周知,是一个复杂得多的系统设计,如果您刚开始,我不建议您尝试编写它。即使是非常资深的程序员也发现构建一个健壮的系统非常困难。由于您是异步的,因此您无法调用阻止的 API。就像从数据库读取数据或向其他服务器发送消息一样,必须异步执行。即使从文件系统读取/写入也会减慢您的单线程速度,从而降低您的可扩展性。一旦你去异步,如果你想保持单线程移动,那么它一直都是异步的。这就是它变得具有挑战性的地方,因为最终你会遇到一个 API,比如数据库,它不是异步的,你必须在某种程度上采用更多的线程。

The good news is there are other solutions that use this lower level API already built that you can use. NodeJS, Vertx, Netty, Apache Mina, Play Framework, Twisted Python, Stackless Python, etc. There might be some obscure library for C++, but honestly I wouldn't bother. Server technology doesn't require the very fastest languages because it's IO bound more than CPU bound. If you are a die hard performance nut use Java. It has a huge community of code to pull from and it's speed is very close (and sometimes better) than C++. If you just hate it go with Node or Python.

好消息是还有其他解决方案使用已经构建的较低级别的 API,您可以使用。NodeJS、Vertx、Netty、Apache Mina、Play Framework、Twisted Python、Stackless Python 等。C++ 可能有一些晦涩的库,但老实说我不会打扰。服务器技术不需要最快的语言,因为它的 IO 限制比 CPU 限制更多。如果您是顽固的性能爱好者,请使用 Java。它有一个庞大的代码社区可以从中提取,并且它的速度非常接近(有时甚至更好)比 C++。如果您只是讨厌它,请使用 Node 或 Python。

回答by Mark

Yes, yes it does. :D

是的,是的。:D

The earlier answers lack imagination. I see no more reason to use AJAX if websockets are available to you.

前面的答案缺乏想象力。如果您可以使用 websockets,我认为没有更多理由使用 AJAX。