当前位置: 首页 > 知识库问答 >
问题:

问模式是否适用于Akka IO演员?

蔚俊人
2023-03-14

假设我有一个IO Actor连接,能够通过TCP发送和接收消息。在我的演员中,我要求连接的另一方做出回应:

 connection.ask(ByteString("stuff")).collect {
    case Received(response) => log.debug(response.utf8String)
 }

使用此代码,ask future超时,而包含参与者接收ask模式之外的原始消息。

你能在Akka IO演员身上使用ask模式吗?若否,原因为何?

共有2个答案

韩宜春
2023-03-14

作为对@ghik答案的补充,这里大致介绍了我如何创建一个中间参与者,以便在我的其他参与者上启用IO的ask模式。

class IOAskHandlerActor(address: InetSocketAddress) extends Actor {
   override def receive = {
      // Connection setup code omitted    
      case Connected(remote, local) =>
         // other code omitted
         context become latch(sender())
   }

   def latch(connection: ActorRef): Receive = {
      case outgoing =>
         context become receiving(connection, sender())
         connection ! MySerializer.write(outgoing)
   }

   def receiving(connection: ActorRef, asker: ActorRef): Receive = {
      case Received(incoming) =>
         context become latch(connection)
         asker ! MySerializer.read(incoming)
   }
}

此类实例可以asked以获得响应。注意,我只对一个同时询问者(这是我的用例)进行了测试,这可能不适用于多个询问者。

法弘亮
2023-03-14

我不知道建筑的细节,但以下是我如何向自己解释的:

Akka IO连接器角色的问题在于它们不能以请求-响应方式工作。如果你仔细想想,这是有道理的,因为TCP不是一个请求-响应协议。TCP甚至没有消息的概念。从程序员的角度来看,TCP连接只是一对连续的字节流——每个方向一个。就这样。

Akka IO是网络协议之上的最小参与者层,因此它模仿这种行为也就不足为奇了。当TCP参与者从网络接收到一些数据时,它只知道一件事——它应该向最初发送Connect消息的参与者发送Received消息。这就是全部。它不知道从网络接收到的数据与您先前发送的数据有什么关联。

除此之外,ask模式仅在以下假设下工作:A向某个参与者发送消息时,它将通过将消息准确地发送给A的发送者来响应B。我们已经知道,TCP actor不会这样做——它只是将所有内容发送给原始Connect消息的发送者。

之所以需要这种假设,是因为ask模式实际上创建了某种“幻影”参与者,该参与者被设置为使用ask发送的消息的发送者。然后,这个“幻影”参与者将接收响应并调用将来注册的所有回调。请注意,这些回调是完全独立于发送参与者调用的,也就是说,它们可能与发送参与者并发运行!

因此,我最终得出结论,像这样使用的ask模式对Akka IO不起作用,因为对于这样的抽象来说,它的级别太低了。如果您仍然需要它,您需要在Akka IO之上创建自己的抽象层,例如,一些简单的中间参与者,涵盖TCP连接器参与者并实现请求-响应行为。

 类似资料:
  • 我收到一个编译错误: 然而,当我移除mapstruct注释处理器时,它可以很好地编译。 所以我认为mapstruct是在类生成之前扫描它们?对此有什么解决方案吗?

  • 我正在将tomcat服务器从tomcat7升级到Tomcat8。但Struts1.1似乎不能在Tomcat8上工作。有人知道Tomcat8不支持Struts1.1吗。 下面是堆栈跟踪

  • 问题内容: 特别是,我正在编写Django RESTful API来支持iOS应用程序,每当编写用于处理POST请求的方法时,我都会不断遇到Dj​​ango的CSRF保护。 我的理解是,iOS管理的cookie不会被应用程序共享,这意味着我的会话cookie是安全的,并且没有其他应用程序可以使用它们。这是真的?如果是这样,我可以将我所有的API函数都标记为CSRF免除吗? 问题答案: 那不是CSR

  • 我已经完成了如下的 nuget 安装: 关于我的测试项目。 我有一个类似的测试: 我能做些什么来解决这个问题并查看我的测试? 补遗 我在4.6.1下工作,所以还不是核心。 关于同一个主题但没有帮助的问题: 为什么xunit运行程序找不到我的测试 此响应 和这个类似的 xunit.runner。visualstudio无法在Visual Studio 2013更新4上工作 所以到处都有,但都没用..

  • 幕布支持将文档用演示模式展现,演示模式能够简单而有条理地展示你的想法。 点击右上角「演示模式」按钮,即可开启演示模式。 演示模式下,文档不可编辑,但仍可展开/收缩节点。 右上角菜单栏分别为: 切换日间/夜间模式; 放大; 缩小; 退出演示模式。

  • 问题内容: 我正在尝试使用选择器将图像放置在另一个图像上,但是我发现将图像放置在一个元素之前(仅在其他某个元素之前)根本不起作用。具体来说,我的风格是: 我发现这很好用: 但这不是: 我可以使用或元素代替它,浏览器可以将我的图像正确地覆盖在该元素中的图像上,但是如果我将overlay类应用于自身,则无法正常工作。 我希望这项工作能够正常进行,因为这会让我感到不舒服,但更重要的是,我有大约100个我