我正在学习Akka和Scala并试图用它构建一个简单的聊天服务器。我编写了以下代码来创建一个简单的会话管理器来管理新创建的Actors。我能够创建新的actor并将ActorRef放到HashMap中,但是当我尝试向特定的Actor发送消息时,该消息就不会被Actor接收。
这是代码。
import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._
import scala.collection.mutable.HashMap
case class ChatMsg(from:String,message:String)
case class Login(username:String)
class Session(userID:String) extends Actor{
val loginTime = System.currentTimeMillis
println(s"Session created time :$loginTime")
def receive ={
case ChatMsg(from,message) => println(s"message :$message from $from !")
}
}
class SessionManager extends Actor{
val system = ActorSystem("ChatSession")
val sessions = new HashMap[String,ActorRef]
val inbox = Inbox.create(system)
def receive ={
case Login(username) =>
println(s"$username Login, now create Actor")
val session = system.actorOf(Props(new Session(username)))
sessions += (username->session)
println(s"session added $sessions")
case ChatMsg(from,message) =>
sessions(from) ! message
}
}
object MyAkkaTest extends App {
val system = ActorSystem("MyAkkaTest")
val user = system.actorOf(Props[SessionManager],"MyActor")
val inbox = Inbox.create(system)
user ! Login("Mary")
user ! Login("John")
user ! ChatMsg("Mary","this is a testing message") //this message can never sent...
}
答案 0 :(得分:2)
问题是你的Session actor期望获得ChatMsg类型的消息,但是你发送的是一个String。
您的主要方法是将ChatMsg对象发送到SessionManager actor。 SesionManager正在接收它,并通过模式匹配将其提取到字段; from和message,两者都是String类型。然后它找到相关的Session actor,并向它发送从ChatMsg对象中提取的消息。因此,它只是发送ChatMsg对象的消息部分,而不是ChatMsg对象本身。
解决它的最简单方法是在SessionManager的receive方法中进行模式匹配,绑定接收到的实际ChatMsg对象的名称,然后将其发送给Session actor。您可以通过在模式匹配前加上" name"来做到这一点。 @ pattern:
class SessionManager extends Actor{
val system = ActorSystem("ChatSession")
val sessions = new HashMap[String,ActorRef]
val inbox = Inbox.create(system)
def receive ={
case Login(username) =>
println(s"$username Login, now create Actor")
val session = system.actorOf(Props(new Session(username)))
sessions += (username->session)
println(s"session added $sessions")
case chatMsg @ ChatMsg(from,message) =>
sessions(from) ! chatMsg
}
}