Nodejs:Ajax 与 Socket.IO,优缺点

发布于 2024-12-01 07:33:09 字数 1700 浏览 0 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半衾梦 2024-12-08 07:33:09

该线程中有很多非常不准确的常见错误信息。

TL/DR;
WebSocket 取代应用程序的 HTTP!它是由谷歌在微软和许多其他领先公司的帮助下设计的。所有浏览器都支持它。 没有缺点。

SocketIO 构建在 WebSocket 协议之上 (RFC 6455)。它的设计初衷是完全取代 AJAX。它不存在任何可扩展性问题。它的工作速度比 AJAX 更快,同时消耗的资源少一个数量级。

AJAX 已有 10 年历史,构建在单个 JavaScript XMLHTTPRequest 函数允许回调到服务器而无需重新加载整个页面。

换句话说,AJAX 是一种具有单个 JavaScript 函数的文档协议 (HTTP)。

相比之下,WebSocket 是一种旨在完全取代 HTTP 的应用程序协议。当您升级 HTTP 连接(通过请求 WebSocket 协议)时,您可以启用与服务器的双向全双工通信,并且不涉及任何协议握手。使用 AJAX,您要么必须启用 keep-alive(与 SocketIO 相同,只是较旧的协议),要么强制进行新的 HTTP 握手,这会在每次发出 AJAX 请求时使服务器陷入困境。

运行在 Node 之上的 SocketIO 服务器仅使用 4GB 内存和单个 CPU,就可以在 keep-alive 模式下处理 100,000 个并发连接,这个限制是由 V8 垃圾收集引擎而不是协议造成的。即使在您最疯狂的梦想中,您也永远无法通过 AJAX 实现这一目标。

为什么 SocketIO 速度如此之快并且消耗的资源如此之少

其主要原因是,WebSocket 是为应用程序设计的,而 AJAX 是一种使应用程序能够在文档协议的顶部。

如果您深入研究 HTTP 协议并使用 MVC 框架,您将看到单个 AJAX 请求实际上会将 700-900 字节的协议负载传输到 AJAX 到 URL(没有任何您自己的有效负载)。与此形成鲜明对比的是,WebSocket 使用大约 10 个字节或大约少 70 倍的数据来与服务器通信。

由于 SocketIO 保持开放连接,因此无需握手,并且服务器响应时间仅限于到服务器本身的往返时间或 ping 时间。

有错误信息认为套接字连接是端口连接;它不是。套接字连接只是表中的一个条目。消耗资源极少,单台服务器可提供1,000,000+ WebSocket连接。 AWS XXL 服务器可以并且确实托管超过 1,000,000 个 SocketIO 连接。

AJAX 连接将 gzip/deflate 整个 HTTP 标头、解码标头、编码标头并启动 HTTP 服务器线程来处理请求,同样,因为这是一个文档协议;服务器被设计成一次性吐出文档。

相比之下,WebSocket 只是在连接表中存储一个条目,大约 40-80 字节。字面意思就是这样。根本不发生任何轮询。

WebSocket 的设计目的是为了扩展。

至于 SocketIO 是混乱的......事实并非如此。 AJAX 很混乱,你需要承诺/响应。

使用 SocketIO,您只需拥有发射器和接收器;他们甚至不需要互相了解;不需要承诺系统:

要请求用户列表,您只需向服务器发送一条消息...

socket.emit("giveMeTheUsers");

当服务器准备就绪时,它会向您发送另一条消息。田田,你完了。因此,要处理用户列表,您只需说出当您收到所需的响应时要执行的操作...

socket.on("HereAreTheUsers", showUsers(data) );

就是这样。哪里乱了?好吧,没有:) 关注点分离?为你完成。锁定客户让他们知道必须等待?他们不必等待 :) 无论何时您都可以获得新的用户列表...服务器甚至可以通过这种方式回放任何 UI 命令...客户端可以连接到每个其他甚至不需要使用带有WebRTC的服务器...

SocketIO中的聊天系统? 10行代码。实时视频会议? 80 行代码 是的...卢克...加入我。使用正确的协议来完成工作...如果您正在编写应用程序...请使用应用程序协议。

我认为这里的问题和困惑来自于习惯使用 AJAX 的人们,认为他们需要客户端上的所有额外承诺协议和后端上的 REST API...好吧,你不知道't。 :) 不再需要了 :)

是的,您没看错...当您决定切换到 WebSocket 时,不再需要 REST API。 REST实际上已经过时了。如果您编写桌面应用程序,您是否使用 REST 与对话框进行通信?不:)那太愚蠢了。

SocketIO,利用 WebSocket 为您做同样的事情......您可以开始将客户端视为应用程序的简单对话框。您根本不再需要休息。

事实上,如果您在使用 WebSocket 的同时尝试使用 REST,那么就像使用 REST 作为桌面对话框的通信协议一样愚蠢......完全没有意义。

你说什么,蒂米?其他想要使用您的应用程序的应用程序怎么办?您应该让他们访问 REST? Timmy...WebSocket 已经问世 4 年了...只需让他们使用 WebSocket 连接到您的应用程序,并让他们使用那个协议请求消息...它将消耗 50 倍的资源,速度更快,开发起来也容易 10 倍……为什么在创造未来时还要支持过去呢?

当然,REST 有一些用例,但它们都是针对旧的和过时的系统......大多数人还不知道。

更新:

很多人最近问我,他们如何在 2018 年(现在很快就要到 2019 年)开始使用 WebSocket 编写应用程序,一旦他们使用 Socket,门槛似乎非常高。他们不知道还能去哪里,也不知道该学什么。

幸运的是,过去 3 年对 WebSocket 来说非常友好……

现在有 3 个主要框架支持 REST 和 WebSocket,甚至支持 IoT 协议或其他最小/快速协议(如 ZeroMQ),而且您不需要不必担心任何事情;您只需获得开箱即用的支持。

注意:虽然 Meteor 是迄今为止最受欢迎的,但我将其排除在外,因为尽管它们是一个资金非常非常充足的 WebSocket 框架,但任何使用 Meteor 编码了几年的人都会告诉您,这是一个内部混乱和规模化的噩梦。有点像 WordPress 之于 PHP,它在那里,很流行,但制作得不是很好。考虑不周,很快就会死掉。抱歉,Meteor 的朋友们,但是看看与 Meteor 相比的其他 3 个项目,您会在同一天抛弃 Meteor :)

使用以下所有框架,只需编写一次服务,即可获得 REST 和 WebSocket 支持。更重要的是,只需一行配置代码即可在几乎所有后端数据库之间进行交换。

Feathers 最容易使用,前后端工作方式相同,支持大部分功能,Feathers 是轻量级的集合现有工具(如 Express)的重量包装器。使用feathers-vuex等出色的工具,您可以创建完全可模拟的不可变服务,支持REST、WebSocket和其他协议(使用Primus),并获得免费的完整CRUD操作,包括搜索和分页,而无需一行代码(只需一些配置)。对于生成的数据也非常有效,例如 json-schema-faker 所以你不仅可以完全模拟事物,您还可以使用随机但有效的数据来模拟它。您可以连接一个应用程序来支持预先输入搜索、创建、删除和编辑,无需代码(只需配置)。你们中的一些人可能知道,正确的代码通过配置是自修改代码的最大障碍。 Feathers 做得很好,并将推动您在未来的应用程序设计中走在前列。

Moleculer 不幸的是,Moleculer 在后端的表现比 Feathers 好一个数量级。虽然 Feathers 可以工作,并且可以让你扩展到无限大,但 Feathers 甚至没有开始考虑诸如生产集群、实时服务器控制台、容错、开箱即用的管道日志或 API 网关之类的事情(虽然我已经构建了Feathers 的生产 API 网关,Moleculer 就是这样做的,而且更好)。 Moleculer 在流行度和新功能方面也比任何 WebSocket 框架增长最快。

Moleculer 的制胜优势是您可以将 Feathers 或 ActionHero 前端与 Moleculer 后端结合使用,虽然您失去了一些生成器,但您获得了很多生产质量。

因此,我建议在前端和后端学习 Feathers,一旦您制作了第一个应用程序,请尝试将后端切换到 Moleculer。 Moleculer 更难上手,但这只是因为它为您解决了所有扩展问题,而这些信息可能会让新用户感到困惑。

ActionHero 此处列出作为可行的替代方案,但 Feathers 和 Moleculer 是更好的实现。如果 ActionHero 的任何内容不适合您,请不要使用它;上面有两种更好的方法可以为您提供更多、更快的服务。

注意: API 网关是未来,上述所有 3 个都支持它们,但 Moleculer 确实为您提供了开箱即用的功能。 API 网关可让您管理客户端交互,允许缓存、记忆、客户端到客户端消息传递、黑名单、注册、容错和所有其他扩展问题由单个平台组件处理。将 API 网关与 Kubernetes 结合起来,可以让您以尽可能少的问题进行无限扩展。它是可扩展应用程序的最佳设计方法。

2021 年更新

行业已经发展得如此之快,您甚至不需要关注协议。 GraphQL 现在默认使用 WebSocket!只需查看如何使用订阅即可。最快的处理方法将会为您出现。

如果您使用 Vue、React 或 Angular,那么您很幸运,因为有适合您的原生 GraphQL 实现!只需使用 GraphQL 订阅从服务器调用您的数据,该数据对象就会保持最新状态并自行

当您需要使用旧系统时,GraphQL 甚至会为您回退到 REST,并且订阅仍将使用套接字进行更新。当您迁移到 GraphQL 时,一切都迎刃而解。

是的,如果你想“什么?!?”当您听说您可以像 FireBase 一样简单地订阅服务器对象,并且它会为您自行更新。是的。现在确实如此。只需使用 GraphQL 订阅即可。它将使用 WebSocket。

聊天系统? 1行代码。
实时视频系统? 1行代码。
拥有 10MB 开放世界数据并在 100 万实时用户之间共享的视频游戏? 1行代码。该代码现在只是您的 GQL 查询。

只要您构建或使用正确的后端,所有这些实时工作现在都可以通过 GQL 订阅为您完成。尽快进行转换,不再担心协议问题。

There is a lot of common misinformation in this thread that is very inaccurate.

TL/DR;
WebSocket replaces HTTP for applications! It was designed by Google with the help of Microsoft and many other leading companies. All browsers support it. There are no cons.

SocketIO is built on top of the WebSocket protocol (RFC 6455). It was designed to replace AJAX entirely. It does not have scalability issues what-so-ever. It works faster than AJAX while consuming an order of magnitude fewer resources.

AJAX is 10 years old and is built on top of a single JavaScript XMLHTTPRequest function that was added to allow callbacks to servers without reloading the entire page.

In other words, AJAX is a document protocol (HTTP) with a single JavaScript function.

In contrast, WebSocket is a application protocol that was designed to replace HTTP entirely. When you upgrade an HTTP connection (by requesting WebSocket protocol), you enable two-way full duplex communication with the server and no protocol handshaking is involved what so ever. With AJAX, you either must enable keep-alive (which is the same as SocketIO, only older protocol) or, force new HTTP handshakes, which bog down the server, every time you make an AJAX request.

A SocketIO server running on top of Node can handle 100,000 concurrent connections in keep-alive mode using only 4gb of ram and a single CPU, and this limit is caused by the V8 garbage collection engine, not the protocol. You will never, ever achieve this with AJAX, even in your wildest dreams.

Why SocketIO so much faster and consumes so much fewer resources

The main reasons for this is again, WebSocket was designed for applications, and AJAX is a work-around to enable applications on top of a document protocol.

If you dive into the HTTP protocol, and use MVC frameworks, you'll see a single AJAX request will actually transmit 700-900 bytes of protocol load just to AJAX to a URL (without any of your own payload). In striking contrast, WebSocket uses about 10 bytes, or about 70x less data to talk with the server.

Since SocketIO maintains an open connection, there's no handshake, and server response time is limited to round-trip or ping time to the server itself.

There is misinformation that a socket connection is a port connection; it is not. A socket connection is just an entry in a table. Very few resources are consumed, and a single server can provide 1,000,000+ WebSocket connections. An AWS XXL server can and does host 1,000,000+ SocketIO connections.

An AJAX connection will gzip/deflate the entire HTTP headers, decode the headers, encode the headers, and spin up a HTTP server thread to process the request, again, because this is a document protocol; the server was designed to spit out documents a single time.

In contrast, WebSocket simply stores an entry in a table for a connection, approximately 40-80 bytes. That's literally it. No polling occurs, at all.

WebSocket was designed to scale.

As far as SocketIO being messy... This is not the case at all. AJAX is messy, you need promise/response.

With SocketIO, you simply have emitters and receivers; they don't even need to know about each-other; no promise system is needed:

To request a list of users you simply send the server a message...

socket.emit("giveMeTheUsers");

When the server is ready, it will send you back another message. Tada, you're done. So, to process a list of users you simply say what to do when you get a response you're looking for...

socket.on("HereAreTheUsers", showUsers(data) );

That's it. Where is the mess? Well, there is none :) Separation of concerns? Done for you. Locking the client so they know they have to wait? They don't have to wait :) You could get a new list of users whenever... The server could even play back any UI command this way... Clients can connect to each other without even using a server with WebRTC...

Chat system in SocketIO? 10 lines of code. Real-time video conferencing? 80 lines of code Yes... Luke... Join me. use the right protocol for the job... If you're writing an app... use an app protocol.

I think the problem and confusion here is coming from people that are used to using AJAX and thinking they need all the extra promise protocol on the client and a REST API on the back end... Well you don't. :) It's not needed anymore :)

yes, you read that right... a REST API is not needed anymore when you decide to switch to WebSocket. REST is actually outdated. if you write a desktop app, do you communicate with the dialog with REST? No :) That's pretty dumb.

SocketIO, utilizing WebSocket does the same thing for you... you can start to think of the client-side as simple the dialog for your app. You no longer need REST, at all.

In fact, if you try to use REST while using WebSocket, it's just as silly as using REST as the communication protocol for a desktop dialog... there is absolutely no point, at all.

What's that you say Timmy? What about other apps that want to use your app? You should give them access to REST? Timmy... WebSocket has been out for 4 years... Just have them connect to your app using WebSocket, and let them request the messages using that protocol... it will consume 50x fewer resources, be much faster, and 10x easier to develop... Why support the past when you're creating the future?

Sure, there are use cases for REST, but they are all for older and outdated systems... Most people just don't know it yet.

UPDATE:

A LOT of people have been asking me recently how can they start writing an app in 2018 (and now soon 2019) using WebSockets, that the barrier seems really high, that once they play with Socket.IO they don't know where else to turn or what to learn.

Fortunately the last 3 years have been very kind to WebSockets...

There are now 3 major frameworks that support BOTH REST and WebSocket, and even IoT protocols or other minimal/speedy protocols like ZeroMQ, and you don't have to worry about any of it; you just get support for it out of the box.

Note: Although Meteor is by far the most popular, I am leaving it out because although they are a very, very well-funded WebSocket framework, anyone who has coded with Meteor for a few years will tell you, it's an internal mess and a nightmare to scale. Sort of like WordPress is to PHP, it is there, it is popular, but it is not very well made. It's not well-thought out, and it will soon die. Sorry Meteor folks, but check out these 3 other projects compared to Meteor, and you will throw Meteor away the same day :)

With all of the below frameworks, you write your service once, and you get both REST and WebSocket support. What's more, it's a single line of config code to swap between almost any backend database.

Feathers Easiest to use, works the same on the front and backend, and supports most features, Feathers is a collection of light-weight wrappers for existing tools like express. Using awesome tools like feathers-vuex, you can create immutable services that are fully mockable, support REST, WebSocket and other protocols (using Primus), and get free full CRUD operations, including search and pagination, without a single line of code (just some config). Also works really great with generated data like json-schema-faker so you can not only fully mock things, you can mock it with random yet valid data. You can wire up an app to support type-ahead search, create, delete and edit, with no code (just config). As some of you may know, proper code-through-config is the biggest barrier to self-modifying code. Feathers does it right, and will push you towards the front of the pack in the future of app design.

Moleculer Moleculer is unfortunately an order of magnitude better at the backend than Feathers. While feathers will work, and let you scale to infinity, feathers simply doesn't even begin to think about things like production clustering, live server consoles, fault tolerance, piping logs out of the box, or API Gateways (while I've built a production API gateway out of Feathers, Moleculer does it way, way better). Moleculer is also the fastest growing, both in popularity and new features, than any WebSocket framework.

The winning strike with Moleculer is you can use a Feathers or ActionHero front-end with a Moleculer backend, and although you lose some generators, you gain a lot of production quality.

Because of this I recommend learning Feathers on the front and backend, and once you make your first app, try switching your backend to Moleculer. Moleculer is harder to get started with, but only because it solves all the scaling problems for you, and this information can confuse newer users.

ActionHero Listed here as a viable alternative, but Feathers and Moleculer are better implementations. If anything about ActionHero doesn't Jive with you, don't use it; there are two better ways above that give you more, faster.

NOTE: API Gateways are the future, and all 3 of the above support them, but Moleculer literally gives you it out of the box. An API gateway lets you massage your client interaction, allowing caching, memoization, client-to-client messaging, blacklisting, registration, fault tolerance and all other scaling issues to be handled by a single platform component. Coupling your API Gateway with Kubernetes will let you scale to infinity with the least amount of problems possible. It is the best design method available for scalable apps.

Update for 2021:

The industry has evolved so much that you don't even need to pay attention to the protocol. GraphQL now uses WebSockets by default! Just look up how to use subscriptions, and you're done. The fastest way to handle it will occur for you.

If you use Vue, React or Angular, you're in luck, because there is a native GraphQL implementation for you! Just call your data from the server using a GraphQL subscription, and that data object will stay up to date and reactive on it's own.

GraphQL will even fall-back to REST for you when you need to use legacy systems, and subscriptions will still update using sockets. Everything is solved when you move to GraphQL.

Yes, if you thought "WTH?!?" when you heard you can simply subscribe, like with FireBase, to a server object, and it will update itself for you. Yes. That's now true. Just use a GraphQL subscription. It will use WebSockets.

Chat system? 1 line of code.
Real time video system? 1 line of code.
Video game with 10mb of open world data shared across 1m real-time users? 1 line of code. The code is just your GQL query now.

As long as you build or use the right back-end, all this realtime stuff is now done for you with GQL subscriptions. Make the switch as soon as you can and stop worrying about protocols.

垂暮老矣 2024-12-08 07:33:09

Socket.IO 在客户端和服务器之间使用持久连接,因此根据服务器端的资源,您将达到并发连接的最大限制,而相同的资源可以服务更多的 Ajax 异步请求。

Socket.IO主要是为客户端和服务器之间的实时双向连接而设计的,在某些应用程序中不需要保持永久连接。另一方面,Ajax 异步连接应该通过 HTTP 连接设置阶段,并在每个请求中发送标头数据和所有 cookie。

Socket.IO 被设计为单进程服务器,并且可能存在可扩展性问题,具体取决于您绑定的服务器资源。

当您最好缓存客户端请求的结果时,Socket.IO 不太适合应用程序。

Socket.IO 应用程序面临 SEO 优化和搜索引擎索引方面的困难。

Socket.IO 不是一个标准,也不等同于 W3C Web Socket API,如果浏览器支持,它使用当前的 Web Socket API,socket.io 由一个人创建,用于解决实时应用程序中的跨浏览器兼容性,并且很年轻,大约 1 年老的。与ajax/jquery相比,它的学习曲线、更少的开发人员和社区资源、长期维护以及未来更少的需求或更好的选择对于开发团队是否基于socket.io制作代码可能很重要。

Socket.IO uses persistent connection between client and server, so you will reach a maximum limit of concurrent connections depending on the resources you have on server side, while more Ajax async requests can be served with the same resources.

Socket.IO is mainly designed for realtime and bi-directional connections between client and server and in some applications there is no need to keep permanent connections. On the other hand Ajax async connections should pass the HTTP connection setup phase and send header data and all cookies with every request.

Socket.IO has been designed as a single process server and may have scalability issues depending server resources that you are bound to.

Socket.IO in not well suited for applications when you are better to cache results of client requests.

Socket.IO applications face with difficulties with SEO optimization and search engine indexing.

Socket.IO is not a standard and not equivalent to W3C Web Socket API, It uses current Web Socket API if browser supports, socket.io created by a person to resolve cross browser compatibility in real time apps and is so young, about 1 year old. Its learning curve, less developers and community resources compared with ajax/jquery, long term maintenance and less need or better options in future may be important for developer teams to make their code based on socket.io or not.

成熟的代价 2024-12-08 07:33:09

发送单向消息并调用它们的回调可能会变得非常混乱。

$.get('/api', sendData, returnFunction);
socket.emit('sendApi', sendData); socket.on('receiveApi', returnFunction);

这就是 dnode 和 nowjs 构建在 socket.io 之上的原因使事情变得易于管理。仍然是事件驱动,但不放弃回调。

Sending one way messages and invoking callbacks to them can get very messy.

$.get('/api', sendData, returnFunction); is cleaner than
socket.emit('sendApi', sendData); socket.on('receiveApi', returnFunction);

Which is why dnode and nowjs were built on top of socket.io to make things manageable. Still event driven but without giving up callbacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文