Websocket API取代REST API?


101

我有一个应用程序,其主要功能通过websocket或长时间轮询实时运行。

但是,大多数站点都是以RESTful方式编写的,这对将来的应用程序和其他客户端非常有用。但是,我正在考虑从REST过渡到用于所有站点功能的websocket API。这将使我更容易将实时功能集成到网站的所有部分。这会增加构建应用程序或移动客户端的难度吗?

我发现有些人已经在做这样的事情:SocketStream


2
@Stegi长时间轮询可以很好地用作后备,而不必担心。
哈利

2
哈利7年后的现在,它对您有何作用?想知道,因为我也想朝那个方向发展。@哈里
德米特里·库德里亚夫采夫

2
@DmitryKudryavtsev我最终没有这样做。传统方法对我来说效果很好,并且难度不大。
哈里

Answers:


97

并不是说这里的其他答案没有道理,它们提出了一些好处。但是,我将违背普遍的共识,并同意您的看法,将Websockets不仅用于实时功能是非常吸引人的。

我正在认真考虑通过Websocket将我的应用程序从RESTful架构迁移到更多的RPC样式。这不是一个“玩具应用程序”,我不是在谈论实时功能,所以我确实有保留。但是我认为走这条路有很多好处,并认为这可能是一个出色的解决方案。

我的计划是使用DNodeSocketIOBackbone。使用这些工具,只需调用RPC样式的函数,即可在客户端和服务器之间传递我的Backbone模型和集合。不再需要管理REST端点,序列化/反序列化对象等等。我还没有使用socketstream,但是看起来值得一试。

在我可以肯定地说这是一个很好的解决方案之前,我还有很长的路要走,我敢肯定这不是每个应用程序的最佳解决方案,但是我坚信这种组合将异常强大。我承认存在一些缺点,例如失去缓存资源的能力。但是我感觉优势将胜过它们。

我有兴趣关注您在探索这种解决方案方面的进展。如果您有任何github实验,请指向我。我还没有,但希望很快。

以下是我一直在收集的待读链接的列表。我不能保证它们都是值得的,因为我只浏览了其中许多。但希望能有所帮助。


关于将Socket.IO与Express结合使用的出色教程。它向socket.io公开了快速会话,并讨论了如何为每个经过身份验证的用户提供不同的房间。

关于具有身份验证,Joyent托管等的node.js / socket.io / backbone.js / express / connect / jade / redis教程:

关于将Pusher与Backbone.js结合使用的教程(使用Rails):

使用客户端上的ribs.js和服务器上的express,socket.io,dnode的node.js构建应用程序。

在DNode中使用Backbone:


1
我刚刚回答了一个相关问题,并提出了一些其他想法:stackoverflow.com/questions/4848642/…–
牛头人

11
“在我可以肯定地说这是一个好的解决方案之前,我还有很长的路要走”-出于好奇,这真的是一个好的解决方案吗?:D
inf3rno 2013年

7
请回复@Tauren。我对您现在要说的内容非常感兴趣。
No_name 2014年

4
@Tauren我也很好奇这是如何实现的?
Kurren 2015年

57

HTTP REST和WebSockets非常不同。HTTP是无状态的,因此Web服务器不需要知道任何信息,因此可以在Web浏览器和代理中进行缓存。如果使用WebSocket,则服务器将变为有状态,并且需要与服务器上的客户端建立连接。

请求-回复通信与推送

仅当需要将数据从服务器送到客户端时,才使用WebSockets ,该通信模式不包括在HTTP中(仅通过变通方法)。如果其他客户端创建的事件需要其他连接的客户端使用,例如在游戏中用户应根据其他客户端行为进行操作,则PUSH会很有帮助。或者,如果您的网站正在监视某些内容,则服务器会一直将数据推送到客户端,例如股市(实时)。

如果不需要从服务器推送数据,通常使用无状态HTTP REST服务器会更容易。HTTP使用简单的请求-应答通信模式。


5
我们非常习惯单向模式,因为我们之前从未有过其他选择。但是现在,随着我的应用程序变得更加发达,对我来说越来越明显的是,使用推送技术的地方越多,响应速度就越快,并且该应用程序就越引人入胜。
哈里

我的应用程序显示了一个朋友列表,例如他们的积分。为什么不实时更新它。如果用户看到他们的朋友在进步,那么他们可能会更愿意跟上。我有某些文档模型,尽管没有经常对其进行准确地更改,但是对其进行了足够的更改,以至于没有实时更新可能会引起一些混乱。在某个时候,您的站点中的很多内容都可以通过推送更新而受益,您可以开始查看代码,其中一半与REST有关,另一半与套接字有关,您可以说,我想统一一下。
哈里

3
这是一个仅使用websocket将通知/命令推送到您的web应用程序的选项(例如带有参数的getUpdate或refreshObjectWithId)。可以在您的webapp(客户端)中分析此命令,然后执行剩余请求以获取特定数据,而不是通过websocket传输数据本身。
Beachwalker

2
出于很多原因,Websocket比REST调用更容易-不仅仅是推送。websocket.org/quantum.html
英国电信

WebSocket令人惊叹,它使服务器可以随时随地发送客户端数据,而不仅仅是响应客户端消息。WebSockets实现了基于消息的协议,因此客户端可以随时接收消息,并且,如果他们正在等待特定的消息,则可以将其他消息排队以便以后处理,重新排序已排队的消息,根据应用程序状态忽略推送消息等。永远不会再编写另一个基于REST的应用程序。Flash借助基于AS3的开源WebSocket实现以及通过ExternalInterface。(addCallback / call)方法回退到浏览器的方式,也使它变得容易。
Triynko 2013年

40

我正在考虑过渡到所有站点功能的WebSocket API

不,您不应该这样做。如果您同时支持两种型号,则没有任何危害。使用REST进行单向通信/简单请求,使用WebSocket进行单向通信,特别是在服务器要发送实时通知时。

的WebSocket比更有效的协议的RESTful HTTP但仍RESTful的HTTP分数超过WebSocket的下面的区域。

  1. 已经为HTTP很好地定义了创建/更新/删除资源。您必须在较低级别为WebSockets实现这些操作。

  2. WebSocket连接在单个服务器上垂直扩展,而HTTP连接在水平服务器上扩展。有一些针对WebSocket水平缩放的专有非基于标准的解决方案。

  3. HTTP具有许多良好的功能,例如缓存,路由,多路复用,gzip压缩等。如果您选择了Websocket,则必须在Websocket的基础上构建这些功能。

  4. 搜索引擎优化可以很好地用于HTTP URL。

  5. 所有代理,DNS,防火墙都尚未完全了解WebSocket通信。它们允许端口80,但可能会通过先侦听端口来限制流量。

  6. WebSocket的安全性是全有或全无的方法。

请查看本文以了解更多详细信息。


3
这是最好的答案。
MattWeiler

1
该主题的最高答案
Sanandrea '17

10

我可以使用TCP(WebSockets)作为主要的Web内容交付策略的唯一问题是,关于如何使用TCP设计网站体系结构和基础结构的资料很少。

因此,您无法从别人的错误中吸取教训,并且发展将会变慢。这也不是“尝试和检验”的策略。

当然,您还将失去HTTP的所有优势(无状态和缓存是更大的优势)。

请记住,HTTP是用于服务于Web内容的TCP的抽象。

并且不要忘了SEO和搜索引擎不会执行websocket。这样您就可以忘记SEO。

我个人建议不要这样做,因为这样做风险太大。

不要使用WS服务网站,而要使用WS服务Web应用程序

但是,如果您有玩具或个人网站,务必尝试尝试一下,尖端。对于企业或公司,您无法证明这样做的风险。


7

我学到了一点教训(艰难的方式)。我制作了一个运行在Ubuntu AWS EC2云服务(使用强大的GPU)上的数字处理应用程序,我想为此做一个前端,以便实时观察其进度。由于它需要实时数据,因此很明显我需要使用websocket来推送更新。

它始于概念验证,并且效果很好。但是,当我们想将其提供给公众时,我们必须添加用户会话,因此我们需要登录功能。不管您如何看待,websocket都必须知道它与哪个用户打交道,因此我们采取了使用websockets进行用户身份验证的捷径。看起来很明显,而且很方便。

实际上,我们不得不花费一些时间使连接可靠。我们从一些廉价的Websocket教程开始,但发现连接断开时,我们的实现无法自动重新连接。当我们切换到socket-io时,一切都得到了改善。Socket-io是必须的!

说了这么多,老实说,我认为我们错过了一些很棒的socket-io功能。Socket-io提供了更多功能,我敢肯定,如果您在最初的设计中考虑到它,那么您可以得到更多的收益。相比之下,我们只是用socket-io的websocket功能替换了旧的websocket,仅此而已。(没有房间,没有通道,...)重新设计本可以使一切变得更强大。但是我们没有时间。这是我们下一个项目要记住的事情。

接下来,我们开始存储越来越多的数据(用户历史记录,发票,交易等)。我们将所有内容都存储在AWS dynamodb数据库中,并且再次使用AIN-IO,通过socket-io从前端到后端传递CRUD操作。我认为我们在那儿走错了路。那是一个错误。

  • 因为不久之后,我们发现Amazon的云服务(AWS)为RESTful应用程序提供了一些出色的负载平衡/扩展工具
  • 现在给人的印象是,我们需要编写许多代码来执行 CRUD操作的握手
  • 最近,我们实现了Paypal集成。我们设法使它起作用。但是同样,所有教程都使用RESTful API来实现。我们必须重写/重新思考他们的示例,以使用websockets实现它们。但是,我们使它运行得相当快。但这确实感觉我们正在逆流而上。

说了这么多,我们下周就要开始了。我们及时到达那里,一切正常。而且速度很快,但是会扩展吗?


只是想知道在我们尝试自己做出此决定时,它是否可以与AWS很好地扩展?
加布

1
@Gabe显然可以在便宜的aws实例上轻松实现100个socket-io连接。我们尚未发现任何性能问题。但是,奇怪的影响之一是,曾经访问过您的网站但随后在选项卡中保持打开状态的人继续使用连接。(而且这种情况通常发生在手机上)。因此,您至少需要一种机制来踢出空闲用户。不过,我还没有付出任何努力,因为我们的表现完全不会受到影响。-因此,无需缩放。
bvdb

4

我会考虑使用两种。每种技术都有自己的优点,没有一种适合所有解决方案的规格。

工作分离是这样的:

  1. WebSockets将是应用程序与需要会话的服务器进行通信的主要方法。这消除了旧版浏览器所需的许多hack(问题是对旧版浏览器的支持将消除这种情况)

  2. RESTful API用于不面向会话(即不需要身份验证)的GET调用,该调用受益于浏览器缓存。一个很好的例子是Web应用程序使用的下拉列表的参考数据。然而。可以比...更频繁地更改

  3. HTML和Javascript。这些构成了Web应用程序的UI。通常,将它们放在CDN上会有所帮助。

  4. 使用WSDL的 Web服务仍然是企业级和跨企业通信的最佳方式,因为它为消息和数据传递提供了明确定义的标准。首先,您将其卸载到Datapower设备以代理Web服务处理程序。

所有这一切都发生在HTTP协议上,该协议已经通过SSL使用安全套接字。

但是对于移动应用程序,websockets无法重新连接到断开的会话(关闭连接后如何重新连接到websocket),并且管理起来并不容易。因此,对于移动应用程序,我仍然建议使用REST API和轮询。

使用WebSockets与REST时要注意的另一件事是可伸缩性。WebSocket会话仍由服务器管理。正确完成的RESTful API是无状态的(这意味着不需要管理服务器状态),因此可扩展性可以在水平方向(比在垂直方向上便宜)增长


2

我要从服务器更新吗?

  • 是:Socket.io
  • 没有休息

Socket.io的缺点是:

  • 可扩展性:WebSockets需要开放的连接以及与Web规模不同的Ops设置。
  • Learnin:我没有无限的学习时间。事情必须完成!

我仍将在项目中使用Socket.io,但不要将REST很好地用于基本的Web表单。


1

基于WebSocket(或长轮询)的传输主要用于服务器和客户端之间的(近)实时通信。尽管在很多情况下都需要使用这种类型的传输,例如聊天或某种类型的实时提要或其他内容,但并非某些Web应用程序的所有部分都必须与服务器双向连接。

REST是一种基于资源的体系结构,众所周知,它比其他体系结构具有自己的优势。WebSockets更倾向于实时地对数据流/提要进行倾斜,这将要求您创建某种基于服务器的逻辑,以便对资源和提要进行优先级划分或区分(如果您不想使用REST)。

我认为,将来当这种传输将更广泛地以数据类型/形式不可知的交付形式被更好地理解/记录时,将来将会有更多的以WebSockets为中心的框架,如socketstream。但是,我认为,这并不意味着它会/应该取代REST,仅仅是因为它提供了许多用例和场景中不一定需要的功能。


-1

那不是一个好主意。该标准甚至尚未最终确定,不同浏览器的支持情况也不尽相同。如果要立即执行此操作,最终将需要回退到Flash或长时间轮询等。将来,它可能仍不会从某种意义上说,由于服务器必须支持使连接对每个用户开放。相反,大多数Web服务器的设计均擅长于快速响应请求并尽快关闭请求。即使是您的操作系统,也必须调整以处理大量的同时连接(每个连接使用更多的临时端口和内存)。尽量在网站上使用REST。


是的,大多数Webserve都擅长HTTP。但是node.js不是Web服务器,而是io库。它可以做TCP就好了。基本上,问题是我们可以将网站设计为使用TCP而不是HTTP。
雷诺斯2011年

应用相同的限制,您仍然会用完短暂的端口/内存,仍然会限制可以同时服务的人数,并且给系统带来不必要的负担。
zeekay

是的,这是有限制的,但是如果您不为每个连接创建新线程,我认为这没什么大不了的。
雷诺斯2011年

我已经为每个用户提供了一个套接字。全球聊天+新闻提要。
哈利

1
我想在2011年这真是个好答案。-所以,我知道你来自哪里。但是在2019年,网络套接字已经成熟。
bvdb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.