WebSocket / REST:客户端连接?

时间:2015-03-19 13:31:03

标签: rest websocket

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

基准测试显示,WebSockets可以提供更多消息,因为该网站显示:http://blog.arungupta.me/rest-vs-websocket-comparison-benchmarks/

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

我的问题是,如果连接始终来自不同的客户端(也许可能是来自同一客户端的某些客户端),该怎么办?基准测试表明它是从我理解的相同客户端连接起来的,这对于保持持续连接是有意义的。

如果用户每分钟只执行一次请求,那么通过REST而不是WebSockets进行通信是不利的,因为服务器可以释放套接字并且可以处理更大的人群说话?

要解决REST的问题,你可以选择垂直扩展,而WebSockets是水平的吗?

这有意义还是我没有?

1 个答案:

答案 0 :(得分:13)

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

实时应用

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

  • 得到很好的支持。
  • 标准
  • 您可以使用发布者/订阅者模型或请求/响应模型(通过为每个请求创建一个correlationId并为其订阅一次)。

小尺寸应用

您的客户端是否需要推送通信和/或发布/订阅,并且您的应用程序不是太大?使用WebSockets。可能没有必要使事情进一步复杂化。

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

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

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

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

我在宠物项目中所做的是将WebSocket端点放在读取模型中,然后在连接时,服务器通过WebSocket向客户端提供connectionID。当客户端通过REST执行操作时,包含一个可选参数,指示“完成时,通过此connectionID通知我”。 REST服务器返回说明命令是否已正确发送到服务总线。队列使用者处理该命令,并且当完成(好或坏)时,如果该命令具有通知请求,则将另一消息放置在“web通知队列”中,该消息指示命令的结果和要通知的connectionID。读取模型订阅此队列,获取消息并将它们转发到适当的WebSocket连接。

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

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

  • 如果将它放在读取模型上,那么您可以轻松访问您的读取数据库以回答快速搜索查询,但是您必须以某种方式结合逻辑来处理命令,作为读取模型的负责人将命令发送到写模型并通知它是否无法执行此操作。

  • 如果将它放在写模型上,那么您可以轻松放置命令,但如果要通过WebSocket回答搜索查询,则需要访问读取模型并读取数据库。

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