WebSocket/REST:客户端连接?

WebSocket/REST: Client connections?

我理解两者背后的主要原则。但是我有一个想法我无法回答。

基准显示 WebSockets 可以处理更多消息,如本网站所示:http://blog.arungupta.me/rest-vs-websocket-comparison-benchmarks/

这是有道理的,因为它声明连接不必关闭和重新打开,http headers 等也是如此

我的问题是,如果连接总是来自 不同的 客户端(也许有些来自同一客户端)怎么办?基准表明,根据我的理解,连接的是相同的客户端,保持持续连接是有意义的。

如果用户每分钟左右只发出一个请求,那么通过 REST 而不是 WebSockets 与 运行 的通信是否有益,因为服务器释放了套接字并且可以处理 更大的人群怎么说?

要解决 REST 的问题,您将通过垂直缩放来解决,而 WebSockets 将是水平的?

这有意义还是我不明白?

这是我迄今为止的经验,我很高兴讨论我在使用 CQRS 的大型应用程序中使用 WebSockets 的结论:

实时应用程序

您正在创建金融应用程序、游戏、聊天或任何需要低延迟、频繁、双向通信的应用程序吗?使用 WebSockets:

  • 支持。
  • 标准。
  • 您可以使用 publisher/subscriber 模型或 request/response 模型(通过为每个请求创建一个 correlationId 并订阅一次)。

小型应用程序

您的客户端是否需要推送通信and/or pub/sub并且您的应用程序不是太大?使用 WebSockets。可能没有必要使事情进一步复杂化。

预期具有一定程度高负载的常规应用程序

如果您不需要非常快地发送命令,并且希望读取的次数远远多于写入的次数,则应该公开一个 REST API 来执行 CRUD(创建、读取、更新、删除),特别是 C_UD。

  • 并非所有设备都喜欢 WebSockets。例如,移动设备可能更喜欢使用 REST,因为保持 WebSocket 连接可能会阻止设备节省电量。
  • 你期待一个结果,即使是超时。即使您可以使用 correlationId 在 WebSockets 中执行 request/response,仍然无法保证响应。当你向系统发送命令时,你需要知道系统是否接受了它。是的,您可以实现自己的逻辑并达到相同的效果,但我的意思是,HTTP 请求具有发送命令所需的语义。
  • 您的应用程序是否经常发送命令?你应该努力进行大量的沟通而不是闲聊,所以你应该批量处理这些变更请求。

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

我在一个宠物项目中所做的是将 WebSocket 端点放置在读取模型中,然后在连接时服务器通过 WebSocket 将连接 ID 提供给客户端。当客户端通过 REST 执行操作时,包括一个可选参数,指示 "when done, notify me through this connectionID"。 REST 服务器 returns 说明命令是否已正确发送到服务总线。队列消费者处理命令,完成后(好或错),如果命令有通知请求,则将另一条消息放置在 "web notification queue" 中,指示命令的结果和要通知的 connectionID。读取模型订阅此队列,获取消息并将它们转发到适当的 WebSocket 连接。

但是,如果您的 REST API 将被非浏览器客户端使用,您可能希望提供一种使用异步 REST 方法检查命令完成的方法:https://www.adayinthelifeof.nl/2011/06/02/asynchronous-operations-in-rest/

我知道,拥有一个可用于发送命令的低延迟 UP 通道非常有吸引力,但如果这样做,您的整体架构就会变得一团糟。例如,如果您使用的是 CQRS 架构,那么您的 WebSocket 端点在哪里?在读取模型或写入模型中?

  • 如果你把它放在读取模型上,那么你可以轻松访问你的读取数据库来回答快速搜索查询,但是你必须以某种方式耦合处理命令的逻辑,即读取模型负责将命令发送到写入模型,如果无法发送则通知。

  • 如果你把它放在写模型上,那么你可以很容易地放置命令,但是如果你想通过 WebSocket 回答搜索查询,你需要访问你的读模型和读数据库.

通过将 WebSockets 视为读取模型的一部分并将命令处理留给 REST 接口,您可以保持读取模型和写入模型之间的松散耦合。