|
@@ -15,51 +15,18 @@ import akka.pattern.ask
|
|
|
import play.api.Play.current
|
|
|
import play.api.libs.concurrent.Execution.Implicits._
|
|
|
|
|
|
-object Robot {
|
|
|
-
|
|
|
- def apply(chatRoom: ActorRef) {
|
|
|
-
|
|
|
- // Create an Iteratee that logs all messages to the console.
|
|
|
- val loggerIteratee = Iteratee.foreach[JsValue](event => Logger("robot").info(event.toString))
|
|
|
-
|
|
|
- implicit val timeout = Timeout(1 second)
|
|
|
- // Make the robot join the room
|
|
|
- chatRoom ? (Join("Robot")) map {
|
|
|
- case Connected(robotChannel) =>
|
|
|
- // Apply this Enumerator on the logger.
|
|
|
- robotChannel |>> loggerIteratee
|
|
|
- }
|
|
|
-
|
|
|
- // Make the robot talk every 30 seconds
|
|
|
- Akka.system.scheduler.schedule(
|
|
|
- 30 seconds,
|
|
|
- 30 seconds,
|
|
|
- chatRoom,
|
|
|
- Talk("Robot", "I'm still alive")
|
|
|
- )
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
object ChatRoom {
|
|
|
-
|
|
|
+
|
|
|
implicit val timeout = Timeout(1 second)
|
|
|
-
|
|
|
- lazy val default = {
|
|
|
- val roomActor = Akka.system.actorOf(Props[ChatRoom])
|
|
|
-
|
|
|
- // Create a bot user (just for fun)
|
|
|
- Robot(roomActor)
|
|
|
-
|
|
|
- roomActor
|
|
|
- }
|
|
|
+
|
|
|
+ lazy val default = Akka.system.actorOf(Props[ChatRoom])
|
|
|
|
|
|
def join(username:String):scala.concurrent.Future[(Iteratee[JsValue,_],Enumerator[JsValue])] = {
|
|
|
|
|
|
(default ? Join(username)).map {
|
|
|
-
|
|
|
- case Connected(enumerator) =>
|
|
|
-
|
|
|
+
|
|
|
+ case Connected(enumerator) =>
|
|
|
+
|
|
|
// Create an Iteratee to consume the feed
|
|
|
val iteratee = Iteratee.foreach[JsValue] { event =>
|
|
|
default ! Talk(username, (event \ "text").as[String])
|
|
@@ -68,9 +35,9 @@ object ChatRoom {
|
|
|
}
|
|
|
|
|
|
(iteratee,enumerator)
|
|
|
-
|
|
|
- case CannotConnect(error) =>
|
|
|
-
|
|
|
+
|
|
|
+ case CannotConnect(error) =>
|
|
|
+
|
|
|
// Connection error
|
|
|
|
|
|
// A finished Iteratee sending EOF
|
|
@@ -78,13 +45,13 @@ object ChatRoom {
|
|
|
|
|
|
// Send an error and close the socket
|
|
|
val enumerator = Enumerator[JsValue](JsObject(Seq("error" -> JsString(error)))).andThen(Enumerator.enumInput(Input.EOF))
|
|
|
-
|
|
|
+
|
|
|
(iteratee,enumerator)
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
class ChatRoom extends Actor {
|
|
@@ -93,7 +60,7 @@ class ChatRoom extends Actor {
|
|
|
val (chatEnumerator, chatChannel) = Concurrent.broadcast[JsValue]
|
|
|
|
|
|
def receive = {
|
|
|
-
|
|
|
+
|
|
|
case Join(username) => {
|
|
|
if(members.contains(username)) {
|
|
|
sender ! CannotConnect("This username is already used")
|
|
@@ -108,7 +75,7 @@ class ChatRoom extends Actor {
|
|
|
case NotifyJoin(username) => {
|
|
|
notifyAll("join", username, "has entered the room")
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case Talk(username, text) => {
|
|
|
notifyAll("talk", username, text)
|
|
|
}
|
|
@@ -116,14 +83,13 @@ class ChatRoom extends Actor {
|
|
|
case Tell(username, text, to) => {
|
|
|
notifyOne(to, "talk", username, text)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
case Quit(username) => {
|
|
|
members = members - username
|
|
|
notifyAll("quit", username, "has left the room")
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
|
|
|
def notifyOne(to: String, kind: String, user: String, text: String) {
|
|
|
val msg = JsObject(
|