无法将消息广播给所有用户

时间:2016-06-14 06:37:52

标签: scala playframework websocket akka

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)。我做错了什么?

0 个答案:

没有答案