我有一个 akka actor,它使用基于此 TCP 连接示例的经典风格:https://doc.akka.io/docs/akka/current/io-tcp.html
我正在尝试从 akka 类型化应用程序内部实例化这个 actor(因为我找不到使用类型化的完全相同的 TCP 连接的示例 - 不确定 API 是否可用?)
implicit val system = ActorSystem(SomeActor(), "typed-actorSystem") // import akka.actor.typed.ActorSystem
val remote = new InetSocketAddress(config.host, config.port)
val client =
system.classicSystem.actorOf(Client.props(remote), "clientActor")
错误:
) java.lang.UnsupportedOperationException: cannot create top-level actor [clientActor] from the outside on ActorSystem with custom user guardian [error] java.lang.UnsupportedOperationException: cannot create top-level actor [clientActor] from the outside on ActorSystem with custom user guardian
我该如何解决这个问题?我必须在其他地方实例化这个 Actor 吗?
最佳答案
您遇到了 Akka Classic 和 Akka Typed 之间的阻抗不匹配问题。
Akka 文档中针对此类情况的一般建议是 use a Classic ActorSystem when needing to coexist with classic code 。文档没有明确说明这一点,但您可以生成类型化的监护人 Actor 的行为,并使所有类型化的 Actor 成为该监护人 Actor 的子级,因此而不是
// typed: guardianBehavior is a Behavior[T], so system is an ActorSystem[T]
val system = ActorSystem(guardianBehavior, "my-actor-system")
你会有
import akka.actor.typed.scaladsl.adapter.ClassicActorSystemOps
// A classic actor system
val system = ActorSystem("my-actor-system")
// Typed guardian, will be in the parental chain of all typed actors
val typedGuardian = system.spawn(guardianBehavior, "typed-guardian")
这确实会阻止您输入的 Actor 通过 context.system.unsafeUpcast
向监护人发送消息;除此之外,ActorSystem[T]
上 T
唯一有意义的操作是将其用作 ActorRef[T]
,所以那些仍然可以使用 typedGuardian
,你只需要手动将其通过(这可以说是比执行 context.system.unsafeUpcast
更有信誉的事情......)
关于scala - 尝试从 akka 类型应用程序内部创建一个经典的 actor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70658402/