我有一个问题,我的程序中没有任何日志输出。请帮我解决问题并告诉我哪里出错了。 该应用程序是一个聊天应用程序。它由 UserActor、Main、RoomActor 组成。
主要:
package Chat
import akka.actor.typed.{ActorRef, ActorSystem, Behavior}
import akka.actor.typed.scaladsl.Behaviors
object Main extends App {
sealed trait MainActor
def apply(): Behavior[MainActor] = Behaviors.setup { context =>
val system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "ChatSystem")
val userActor = system.systemActorOf(UserActor(), "userActor")
val roomActor = system.systemActorOf(RoomActor(), "roomActor")
userActor ! UserActor.CreateUser("John", "Doe", 25, system.deadLetters)
val roomName = "General"
roomActor ! RoomActor.CreateRoom(userActor, roomName)
userActor ! UserActor.SendMessageToRoom(roomActor, "Hello, everyone!", "John")
Thread.sleep(5000)
system.terminate()
Behaviors.receiveMessage {
case _ =>
context.log.info("Unknown message for MainActor")
Behaviors.same
}
}
}
用户演员:
package Chat
import Chat.RoomActor.RoomCommand
import akka.actor.typed.{ActorRef, Behavior}
import akka.actor.typed.scaladsl.Behaviors
import java.util.UUID
object UserActor {
sealed trait UserCommand
case class CreateUser(name: String, surname: String, age: Int, userActor: ActorRef[UserCommand]) extends UserCommand
case class User(name: String, surname: String, age: Int, userId: String, userActor: ActorRef[UserCommand])
case class SendMessageToRoom(room: ActorRef[RoomCommand], content: String, userName: String) extends UserCommand
case class LeftRoomNotification(user: ActorRef[UserCommand], roomName: String) extends UserCommand
case class JoinRoomNotification(user: ActorRef[UserCommand], roomName: String) extends UserCommand
case class ReceiveMessage(sender: ActorRef[UserCommand], content: String) extends UserCommand
def apply(): Behavior[UserCommand] = userBehavior(Map.empty)
private def userBehavior(users: Map[String, User]): Behavior[UserCommand] =
Behaviors.receive{(context, message) =>
message match {
case ReceiveMessage(sender, content) =>
context.log.info(s"User ${context.self} received message from $sender: $content")
Behaviors.same
case SendMessageToRoom(room, content, userName) =>
users.get(userName) match {
case Some(user) =>
room ! RoomActor.BroadcastMessage(user.userActor, content)
case None =>
throw new Exception(s"Unknown User $userName!")
}
Behaviors.same
case CreateUser(name, surname, age, userActor) =>
val userId = UUID.randomUUID().toString
val newUser = User(name, surname, age, userId, userActor)
context.log.info(s"User $newUser added in user list")
context.log.info(s"Created user: $userId")
users + (userId -> newUser)
Behaviors.same
case LeftRoomNotification(user, roomName) =>
context.log.info(s"User $user received LeftRoomNotification for room: $roomName")
Behaviors.same
case JoinRoomNotification(user, roomName) =>
context.log.info(s"User $user received JoinRoomNotification for room: $roomName")
Behaviors.same
case _ =>
context.log.warn("Unknown message for UserActor")
Behaviors.same
}
}
}
房间演员:
package Chat
import Chat.UserActor.{JoinRoomNotification, UserCommand}
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, Behavior}
import java.time.LocalDateTime
import scala.collection.mutable
object RoomActor {
sealed trait RoomCommand
case class CreateRoom(user: ActorRef[UserCommand], roomName: String) extends RoomCommand
case class LeaveRoom(user: ActorRef[UserCommand], roomName: String) extends RoomCommand
case class JoinRoom(user: ActorRef[UserCommand], roomName: String) extends RoomCommand
case class BroadcastMessage(user: ActorRef[UserCommand], content: String) extends RoomCommand
case class Room(roomName: String, owner: ActorRef[UserCommand], creationDate: LocalDateTime, users: mutable.Set[ActorRef[UserCommand]])
def apply(): Behavior[RoomCommand] = roomBehavior(Map.empty)
private def roomBehavior(rooms: Map[String, Room]): Behavior[RoomCommand] =
Behaviors.receive { (context, message) =>
message match {
case CreateRoom(user, roomName) =>
val room = Room(roomName, user, LocalDateTime.now(), mutable.Set(user))
context.log.info(s"$user created room: $roomName")
roomBehavior(rooms + (roomName -> room))
case LeaveRoom(user, roomName) =>
rooms.get(roomName).foreach { room =>
room.users -= user
if(user == room.owner) {
if(room.users.isEmpty) {
context.log.info(s"$user was the owner and the last user in room: $roomName. Removing the room.")
roomBehavior(rooms - roomName)
} else {
val newOwner = room.users.head
context.log.info(s"$user was the owner. Assigning the new owner: $newOwner")
val updatedRoom = room.copy(owner = newOwner)
roomBehavior(rooms + (roomName -> updatedRoom))
}
} else {
context.log.info(s"$user left the room: $roomName")
for (elem <- room.users) {
elem.tell(UserActor.LeftRoomNotification(user, roomName))
}
Behaviors.same
}
}
context.log.info(s"$user left room: $roomName")
Behaviors.same
case JoinRoom(user, roomName) =>
rooms.get(roomName).foreach {room =>
room.users += user
user ! JoinRoomNotification(user, roomName)
}
Behaviors.same
case BroadcastMessage(sender, content) =>
rooms.values.foreach{room =>
room.users.foreach{user =>
if(user != sender) {
user ! UserActor.ReceiveMessage(sender, content)
}
}
}
context.log.info(s"Broadcast message from $sender: $content")
Behaviors.same
case _ =>
throw new IllegalArgumentException("Unknown message for RoomActor")
Behaviors.same
}
}
}
输出为:
15:24:35: Executing ':Main.main()'...
> Task :compileJava NO-SOURCE
> Task :compileScala
[Warn] : -target is deprecated: Use -release instead to compile against the correct platform API.
one warning found
> Task :processResources NO-SOURCE
> Task :classes
> Task :Main.main()
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD SUCCESSFUL in 13s
2 actionable tasks: 2 executed
15:24:49: Execution finished ':Main.main()'.
我已经添加了Thread.sleep(5000),但是程序仍然没有任何日志输出。我尝试添加 root level =“DEBUG”和“info”的 logback.xml。另外,我尝试用 Await.result(system.whenTermulated, Duration.Inf) 替换 Thread.sleep
因为你没有运行任何东西。
Behaviors.xx
只创建一个 actor 工厂,你必须显式地让 ActorSystem
生成它。
object Maim extends App {
sealed trait MainActor
// setup your guardian actor here
val guardianActor: Behavior[Any] = Behaviors.receive { (context, message) =>
// like java constructor here
val userActor = system.systemActorOf(UserActor(), "userActor")
// other...
// react to message
message match {
case _ =>
context.log.info("Unknown message for MainActor")
Behaviors.same
}
}
// start ActorSystem here...
val system: ActorSystem[Nothing] = ActorSystem(guardianActor, "ChatSystem")