假设我有一个 IO Actor connection
能够通过 TCP 发送和接收消息。在我的 Actor 中,我要求连接的另一端做出回应:
connection.ask(ByteString("stuff")).collect {
case Received(response) => log.debug(response.utf8String)
}
看来,使用此代码, future 的询问超时,而是包含 Actor 在询问模式之外接收原始消息。
你可以对 Akka IO Actor 使用 ask 模式吗?如果不是,为什么不呢?
最佳答案
我不详细了解架构,但这是我向自己解释的方式:
这里 Akka IO 连接器参与者的问题是它们不能以请求-响应方式工作。如果您考虑一下 - 这是有道理的,因为 TCP 不是请求-响应协议(protocol)。 TCP 甚至没有消息的概念。从程序员的角度来看,TCP 连接只是一对连续的字节流——每个方向一个。就是这样。
Akka IO 是网络协议(protocol)之上的最小参与者层,因此它模仿这种行为也就不足为奇了。当 TCP 参与者从网络接收到一些数据时,它只知道一件事——它应该发送一个 Received
给最初发送 Connect
的参与者的消息信息。就这样。它不知道它从网络接收到的数据与您之前发送的数据有某种关联。
除此之外,ask
模式仅在您发送消息 A
的假设下有效。对于某些 Actor ,它会回复消息 B
通过将其准确发送给消息的发件人A
.正如我们已经知道的那样,TCP 参与者不会这样做 - 它只是将所有内容发送给原始 Connect
的发送者。信息。
之所以需要这个假设是因为 ask
模式实际上创建了某种“幻像”actor,它被设置为使用 ask
发送的消息的发送者。 .这个“幻像”actor 将接收响应并调用在 Future
上注册的所有回调。 .作为旁注 - 请注意,这些回调是完全独立于发送参与者调用的,即它们可能会同时运行!
所以,我最终得出的结论是 ask
像这样使用的模式不适用于 Akka IO,因为对于这样的抽象来说,它的级别太低了。如果您仍然想要它,您需要在 Akka IO 之上创建自己的抽象层,例如一些简单的中间参与者,涵盖 TCP 连接参与者并实现请求-响应行为。
关于scala - 询问模式是否适用于 Akka IO Actor ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23569168/