WebSocket/REST:客户端连接?

9

我理解两者的主要原则。然而,我有一个问题无法回答。

基准测试显示WebSockets可以处理更多的消息,就像这个网站所展示的那样:http://blog.arungupta.me/rest-vs-websocket-comparison-benchmarks/

这是有道理的,因为它指出连接不必关闭和重新打开,也没有HTTP头等等。

我的问题是,如果连接总是来自不同的客户端(也许还有一些来自同一客户端),会怎样呢?从我所了解的基准测试结果来看,它们都是来自相同的客户端,保持一个恒定的连接是有意义的。

如果用户每分钟只发起一次请求,那么使用REST而不是WebSockets进行通信是否有利于服务器释放套接字并处理更大的人群呢?

为了解决REST的问题,您可以通过垂直扩展来解决,而WebSockets则是水平扩展?

这有道理吗,还是我想多了?

1个回答

17
This is my experience so far, I am happy to discuss my conclusions about using WebSockets in big applications approached with CQRS:
实时应用程序
您是否正在创建需要低延迟、频繁、双向通信的金融应用程序、游戏、聊天或其他类型的应用程序?使用WebSockets:
- 得到良好支持。 - 是标准。 - 您可以使用发布/订阅模型或请求/响应模型(通过为每个请求创建一个关联ID并订阅一次)。
小型应用程序
您需要在客户端进行推送通信和/或发布/订阅,并且您的应用程序不太大吗?使用WebSockets。也许没有必要进一步复杂化事情。
具有某些高负载预期的常规应用程序
如果您不需要非常快地发送命令,并且您期望执行更多的读取而不是写入,则应公开REST API以执行CRUD(创建、读取、更新、删除),特别是C_UD。
  • 并不是所有设备都喜欢使用WebSockets。例如,移动设备可能更喜欢使用REST,因为维护WebSocket连接可能会影响设备的电池寿命。
  • 您期望有一个结果,即使它是超时的。即使您可以使用correlationId在WebSockets中进行请求/响应,仍然不能保证获得响应。当您向系统发送命令时,您需要知道系统是否已接受该命令。是的,您可以实现自己的逻辑并实现相同的效果,但我的意思是,HTTP请求具有您需要发送命令的语义。
  • 您的应用程序发送命令非常频繁吗?您应该努力实现块通信而不是零碎的通信,因此您可能应该批处理这些更改请求。

然后,您应该公开WebSocket端点以订阅特定主题,并执行低延迟的查询-响应,例如填充自动完成框,检查唯一项目(例如:用户名)或在读取模型中进行任何类型的搜索。还可获取有关何时实际处理和完成更改请求(写入)的通知。

在我的宠物项目中,我将WebSocket端点放置在读取模型中,然后在连接时,服务器通过WebSocket向客户端提供连接ID。当客户端通过REST执行操作时,包括一个可选参数,指示“完成后,请通过此连接ID通知我”。 REST服务器返回说,如果命令已正确发送到服务总线,则会发出通知。队列消费者处理命令,并在完成后(无论是正确还是错误),如果命令有通知请求,则在“Web通知队列”中放置另一条消息,指示命令的结果和要通知的连接ID。读取模型订阅了此队列,获取消息并将其转发到适当的WebSocket连接。
然而,如果您的REST API将由非浏览器客户端使用,您可能希望提供一种使用异步REST方法来检查命令完成的方式:https://www.adayinthelifeof.nl/2011/06/02/asynchronous-operations-in-rest/ 我知道,拥有一个低延迟的UP通道可以发送命令非常吸引人,但如果这样做,你的整体架构会变得混乱。例如,如果你正在使用CQRS架构,那么你的WebSocket端点在哪里?在读模型还是写模型中?
  • 如果你把它放在读模型上,那么你可以轻松访问读数据库以快速响应搜索查询,但你必须将处理命令的逻辑与之耦合,使读模型负责向写模型发送命令并在无法执行时通知。
  • 如果你把它放在写模型上,那么你可以轻松地放置命令,但是如果你想通过WebSocket回答搜索查询,那么你需要访问读模型和读数据库。
通过将WebSockets视为读模型的一部分,并将命令处理留给REST接口,你可以保持读模型和写模型之间的松耦合。

不错的答案!我有一个潜在的问题:让我们考虑一个实时Web应用程序,它提供了一堆商品。实时的意思是,商品可能不可用或者价格可能会发生变化等。我认为,WebSocket非常适合这里。但是,如果商品有图片呢?现在,我们正在考虑将所有内容放在WebSocket上,除了通过REST获取的图片(也许后来利用CDN功能)。您对这种设计有什么看法? - Al-un
1
如果您通过WebSocket发送图像,则不能同时发送项目,因此由于实时要求,我会将WS保留给项目,并通过常规HTTP提供图像。因此,除非图像也在实时更改,否则您的方法对我来说看起来不错。 - vtortola
当您说“_不能同时发送项目_”时,您是假定图片以二进制格式发送(而不是Base64编码的长字符串格式),对吗? - Al-un
1
任何Websocket协议都不允许交错数据帧,因此如果您发送了2Mb的数据,则另一端必须在读取下一个数据之前读取它。 - vtortola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接