【问题标题】:Real-Time webapp / Akka actor notifying the websocket connection to send information to client实时 webapp / Akka actor 通知 websocket 连接向客户端发送信息
【发布时间】:2014-02-24 13:23:50
【问题描述】:

我在 Scala 中使用 Play Framework 2.2.1。

我想要实现的场景是:

新注册用户首次登录后,必须对数据库进行一些有趣的更新。
这将是一个相当长的运行过程(大约几秒钟)。
我想要的是在进行所有更新时通知用户(前端),并且他现在可以从这些新创建的链接中受益(无论更新会给他带来什么细节)。

我考虑过在我的控制器中分离一个 Akka Actor,以便处理不同更新所需的逻辑并将它们执行到数据库中。
实际上,在我的情况下,数据库访问是一个阻塞 IO。

我的主要问题是如何利用 websocket 仅在这个长时间运行的任务完成时通知用户。

是否存在一种机制来通知我已经建立的 websocket 连接演员刚刚完成其工作?

【问题讨论】:

  • 您在尝试通过已建立的 WS 连接推送消息时是否遇到特定问题?
  • 实际上,我目前正在研究实现该技巧所需的架构,并且我想知道一种常用的方法来实现这一技巧,因为它在实际的 Play 文档中并不容易透露。 playframework.com/documentation/2.2.x/ScalaWebSockets

标签: web-applications websocket akka actor playframework-2.2


【解决方案1】:

可能是这样的?:

在您的控制器中,当用户第一次发出请求时,调用将要执行不同操作的方法,因为这些是阻塞的,所以将 DB 调用包装在给定的 actor 中,而不是调用一个简单的方法来获取结果,您应该可以要求演员进行操作,这个ask 方法(参见Akka doc)将返回一个未来。

这个未来将被发送到一个给定的演员,该演员持有对不同连接的引用(同时控制器返回一个结果,好的......),然后这个演员应该监听未来的状态,以防万一成功(onSuccess),使用适当的连接向适当的用户推送消息。在第一次创建 WS 连接时,可以检索并保存 out enumerator,想到的一个基本方法是您可以将它们保存在以用户 ID 作为键的映射中。然后,您可以使用这些枚举器将消息推送到客户端。

【讨论】:

  • 对不起,我的意思是数据库访问是阻塞的,而不是非阻塞的。但它不应该改变机制。很多文章都涉及到客户端引发的与 websocket 的连接,我对相反的内容感兴趣。所以你说我可以在我的演员中保留对 websocket 连接的引用,如何?根据文档,websocket 在 REST 调用(控制器的方法)中是“隔离的”,并且只能从其 ws:// url 访问。
  • 是的,但是在创建连接时,您还会返回一个 out 枚举器,这是应该用于向用户推送消息的对象。我更新了我的答案以解决您的评论。
  • 您的解决方案确实有意义。使用两个参与者而不是一个参与者(更新数据库和通知套接字)有什么好处? => 没关系,我想,第二个演员是一个持久的听众,第一个是临时的,需要不阻塞主播放请求的线程。
  • 最好是创建不同的对象来处理不同的任务,也许将来您希望将与数据库交互的代码与其他逻辑分开......另外,将那些东西分开更漂亮执行不同的任务 IMO。
  • 好的,我完全同意,我想确保我没有错过某个特定的 Akka 演员概念,因为我刚刚发现它 :) 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
  • 2021-07-18
  • 2013-04-30
相关资源
最近更新 更多