如何使用WebSocket在play framework 2.5.x中创建多个用户

时间:2016-12-25 11:20:39

标签: scala playframework akka

我按照https://www.playframework.com/documentation/2.5.x/ScalaWebSockets

上的文档进行操作

我和演员写了一个聊天室:

def socket = WebSocket.acceptOrResult[String, String] { request =>
        ActorFlow.actorRef(out => MyWebSocketActor.props(out))
}
import akka.actor._
class MyWebSocketActor(out:ActorRef) extends Actor{
    def receive={
        case msg:String =>{
            out ! ("I received your message:"+msg)
            //println(msg)
        }
    }
}
object MyWebSocketActor{
    def props(out:ActorRef)=Props(new MyWebSocketActor(out))
}

但我在这里遇到了一个问题:当两台设备进入我的聊天室时,他们只有他们的话语。

如何使用Akka Streams和Actor创建聊天室?

1 个答案:

答案 0 :(得分:1)

您需要使用actor为系统建模。 MyWebSocketActor代表单个用户。你需要演员,代表用户的空间。

我写了一个简单的例子(评论中的解释):

object MyWebSocketActor {
  case object Init
}

class MyWebSocketActor(out: ActorRef) extends Actor {

  //you can pass precreated room in constructor or receive it from message,
  //based on your logic
  val room: ActorRef = ???

  //when actor starts, it register self in room, we send Init 
  //message, because actors communications should be in `receive`
  override def preStart(): Unit = {
    self ! Init
  }

  //initial state, waiting joining in room 
  def waitingToJoin: Receive = {
    case Init => room ! Join(self)
    case Joined => context become joined
  }

  //joined state, process messages from out and room
  def joined: Receive = {
    case textFromOut: String => room ! Msg(textFromOut)
    case msg: Msg => out ! msg.toString
  }

  //initial state
  override def receive: Receive = waitingToJoin
}


object Room {
  //request to join
  case class Join(user: ActorRef)
  //join response
  case class Joined(room: ActorRef)
  case class Msg(text: String)
}

class Room extends Actor {

  //users in room
  val users: ListBuffer[ActorRef] = ListBuffer()

  override def receive: Receive = {
    case msg: Msg =>
      //send messages to all users
      users.foreach(u => u ! msg)
    //join request
    case Join(user) =>
      context watch user
      users += user
      user ! Joined(self)
    case Terminated(user) =>
      users -= user
  }

}