package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.libs.json._
import javax.inject._
import play.api.libs.streams._
import akka.stream._
import akka.actor._
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.ActorRef
import akka.actor.Props
import akka.pattern.ask
import akka.util.Timeout
import akka.actor.PoisonPill
import scala.concurrent.duration._
import akka.stream.Materializer
import play.api.cache._
import play.api.libs.iteratee._
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.concurrent._
import play.api.libs.ws.WSClient
//import play.api.cache.
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject() (cache:CacheApi) (implicit actorSystem:ActorSystem,materializer:Materializer) extends Controller {
/**
* Create an Action to render an HTML page with a welcome message.
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/`.
*/
class MyWebSocketActor(out:ActorRef) extends Actor {
def receive = {
case msg:JsValue => {
val (returnMsg,returnCode) = validate(msg)
if(returnCode==404) {
out ! returnMsg
out !PoisonPill
} else if (returnCode==200) {
//send to all
val (enumerator,outChannel) = Concurrent.broadcast[JsValue]
val iteratee:Iteratee[JsValue,Unit] = Iteratee.foreach[JsValue]{returnMsg =>
outChannel.push(returnMsg)
}
println(returnMsg)
}
}
}
}
def validate(msg:JsValue) = {
val user_key = (msg \ "username").get
val username = user_key.toString().stripSuffix("\"").stripPrefix("\"")
val validate_user: Option[String] = cache.get[String](username)
val valid_result = validate_user.toString()
if (valid_result.equals("None")) {
//cache is not set
// println(valid_result)
//add user
cache.set(username,username)
Ok.withSession(username->username)
//notify all users
val successMsg = Json.parse("""{"username":"Server","message":"A new user has been connected"}""")
(successMsg, 200)
}
else {
//cache is already set
//send error msg to new user
val errorMsg = Json.parse("""{"username":"Server","message":"This username is already taken"}""")
(errorMsg, 404)
}
}
object MyWebSocketActor {
def props(out: ActorRef) = Props(new MyWebSocketActor(out))
}
def socket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlow.actorRef(out => MyWebSocketActor.props(out))
}
}
我是Akka的新手并且玩websocket。我在Play 2.5.3中工作。在接收功能的上述代码中,我试图通过val (enumerator,outChannel) = Concurrent.broadcast[JsValue]
连接所有通道,以便我可以向所有连接的用户广播消息。但是没有消息传递给任何用户,但执行了println(returnMsg)
。我做错了什么?