我在我的 akka 應用程式中收到以下運行時錯誤(同時使用 akka 型別和經典)
java.lang.UnsupportedOperationException:不支持從 Actor[akka://my-classic-actor-system/user/ChatServer#1583147696] 外部訪問 ActorContext。Actor 當前沒有處理任何訊息,但 ActorContext 是從 Thread[my-classic-actor-system-akka.actor.default-dispatcher-5,5,run-main-group-0] 呼叫的。
def main(args: Array[String]): Unit = {
val logger = LoggerFactory.getLogger(getClass)
logger.debug("Server starting yo...")
implicit val system = akka.actor.ActorSystem("my-classic-actor-system")
implicit val typedGuardian: ActorRef[Any] =
system.spawn(HttpWebsocketServer(), "ChatServer")
val client = system.actorOf(Client.props(remote), "clientActor")
//..
}
錯誤的來源在 HttpWebsocketServer 內部,它取自( https://github.com/johanandren/chat-with-akka-http-websockets/blob/akka-2.6/src/main/scala/chat/Server。斯卡拉#L101 ):
object HttpWebsocketServer {
def apply(): Behavior[Any] = {
Behaviors.setup[Any] { context =>
implicit val ec: ExecutionContext = context.executionContext
val system = context.system
val chatRoom = context.spawn(ChatRoom(), "chat")
val userParent = context.spawn(SpawnProtocol(), "users")
val maker =
context.spawn(websock.Maker(), "mmaker")
val route =
path("chat") {
get {
handleWebSocketMessages(
newUserFlow(system, chatRoom, userParent)
)
}
}
// needed until Akka HTTP has a 2.6 only release
implicit val materializer: Materializer =
SystemMaterializer(context.system).materializer
implicit val classicSystem: akka.actor.ActorSystem =
context.system.toClassic
Http()
.bindAndHandle(route, "0.0.0.0", 9000)
// future callback, be careful not to touch actor state from in here
.onComplete {
case Success(binding) =>
context.log.debug(
s"Started server at ${binding.localAddress.getHostString}:${binding.localAddress.getPort}"
)
case Failure(ex) =>
ex.printStackTrace()
context.log.error("Server failed to start, terminating")
context.system.terminate()
}
Behaviors.empty
}
}
}
構建.sbt
val AkkaVersion = "2.6.18"
val AkkaHttpVersion = "10.2.7"
libraryDependencies = Seq(
"io.netty" % "netty-all" % "4.1.68.Final",
"com.typesafe.akka" %% "akka-actor" % AkkaVersion,
"com.typesafe.akka" %% "akka-actor-typed" % AkkaVersion,
"com.typesafe.akka" %% "akka-stream" % AkkaVersion,
"com.typesafe.akka" %% "akka-stream-typed" % AkkaVersion,
"com.typesafe.akka" %% "akka-http" % AkkaHttpVersion,
"com.typesafe.akka" %% "akka-http-spray-json" % AkkaHttpVersion,
"ch.qos.logback" % "logback-classic" % "1.2.10",
scalaTest % Test
)
如果我在下面的代碼中注釋掉,我不會收到運行時錯誤,所以看起來這就是問題的根源:
implicit val materializer: Materializer =
SystemMaterializer(context.system).materializer
implicit val classicSystem: akka.actor.ActorSystem =
context.system.toClassic
Http()
.bindAndHandle(route, "0.0.0.0", 9000)
// future callback, be careful not to touch actor state from in here
.onComplete {
case Success(binding) =>
context.log.debug(
s"Started server at ${binding.localAddress.getHostString}:${binding.localAddress.getPort}"
)
case Failure(ex) =>
ex.printStackTrace()
context.log.error("Server failed to start, terminating")
context.system.terminate()
}
我不確定我能做些什么來解決這個問題,我正在從系統或子演員創建演員。
uj5u.com熱心網友回復:
不允許在context演員之外使用。你這樣做是為了回饋你的未來。
case Success(binding) =>
context.log.debug(
s"Started server at ${binding.localAddress.getHostString}:${binding.localAddress.getPort}"
)
case Failure(ex) =>
ex.printStackTrace()
context.log.error("Server failed to start, terminating")
context.system.terminate()
問題是參與者背景關系被視為參與者的內部狀態,不能在范圍之外訪問。甚至你的評論都說
// 未來回呼,注意不要從這里觸摸actor狀態
解決方案是在回呼外部預先參考你的logand system(你已經有了這個) 。val回呼看起來像
case Success(binding) =>
log.debug(
s"Started server at ${binding.localAddress.getHostString}:${binding.localAddress.getPort}"
)
case Failure(ex) =>
ex.printStackTrace()
log.error("Server failed to start, terminating")
system.terminate()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/412149.html
標籤:
