I got problem in UserActor, case SendMessageToRoom (20 line of the Actor):
Type mismatch. Required: UserCommand, found: RoomActor.BroadcastMessage
This application is mean to be a Chat. UserActor is an User, Room is a Chat. There is no Main class because it needs fix (doesn't influence on problem). Please, help me solve this problem and describe me what did I done incorrectly.
UserActor:
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
def apply(): Behavior[UserCommand] = userBehavior(Map.empty)
private def userBehavior(users: Map[String, User]): Behavior[UserCommand] =
Behaviors.receive{(context, message) =>
message match {
case SendMessageToRoom(room, content, userName) =>
users.get(userName) match {
case Some(user) =>
user.userActor ! RoomActor.BroadcastMessage(user.userActor, content, room)
}
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 _ =>
context.log.warn("Unknown message for UserActor")
Behaviors.same
}
}
}
RoomActor:
import Chat.UserActor.UserCommand
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ActorRef, Behavior}
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, room: String) extends RoomCommand
def apply(): Behavior[RoomCommand] = roomBehavior(Map.empty)
private def roomBehavior(rooms: Map[String, ActorRef[RoomCommand]]): Behavior[RoomCommand] =
Behaviors.receive { (context, message) =>
message match {
case CreateRoom(user, roomName) =>
val newRoomActor = context.spawn(RoomActor(), roomName)
context.log.info(s"$user created room: $roomName")
roomBehavior(rooms + (roomName -> newRoomActor))
case LeaveRoom(user, roomName) =>
context.log.info(s"$user left room: $roomName")
Behaviors.same
case JoinRoom(user, roomName) =>
context.log.info(s"$user joined room: $roomName")
Behaviors.same
case BroadcastMessage(user, content, room) =>
context.log.info(s"Broadcast message from $user: $content")
Behaviors.same
case _ =>
throw new IllegalArgumentException("Unknown message for RoomActor")
Behaviors.same
}
}
}
I tried make "room" String. Doesn't help. Was another "Type mismatch" problem
case SendMessageToRoom(room, content, userName) =>
users.get(userName) match {
case Some(user) =>
- user.userActor ! RoomActor.BroadcastMessage(user.userActor, content, room)
+ room! RoomActor.BroadcastMessage(user.userActor, content, room)
}
Behaviors.same
aa ! bb
, that's means send the message "bb" to "aa" actor.
Change your object-oriented way of thinking, This is not a method call.
Treat each actor as a human being. On Typed Actor, the message type refers to the language that this person can recognize. !
means talk to this guy,
In your case, the room actor is kind of like a room manager, he has a speaker, and when he receives a message from the person in the room, he will pick up the speaker, and then broadcast it.
For this purpose, the room actor must explicitly maintain all users as a collection that who join this room and, upon receiving a broadcast message, broadcast the message through userCollection.foreach(u => u.actorRef ! message)
.
Or you just have a typing mistake, I hope this answer solves your problem.