尝试从 akka 类型的应用程序内部创建经典演员

Trying to create a classic actor from inside of a akka typed application

我有一个使用基于此 TCP 连接示例的经典样式的 akka actor:https://doc.akka.io/docs/akka/current/io-tcp.html

我正在尝试从 akka 类型的应用程序内部实例化此参与者(因为我找不到使用类型的完全相同的 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

我该如何解决这个问题?我必须在其他地方实例化这个演员吗?

您遇到了 Akka Classic 和 Akka Typed 之间的阻抗不匹配。

Akka 文档中针对此类情况的一般建议是 use a Classic ActorSystem when needing to coexist with classic code。文档没有明确说明,但您可以生成类型化的守护者行为,并让所有类型化的角色成为该守护者角色的 child,而不是

// 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")

这会阻止您键入的演员通过 context.system.unsafeUpcast 向监护人发送消息;除此之外,TActorSystem[T] 有意义的唯一操作是将其用作 ActorRef[T] 的操作,因此它们仍然可以使用 typedGuardian,您只需手动穿线(这可以说是比 context.system.unsafeUpcast... 更有名的事情)