2016-06-13 31 views
1
package controllers 

import javax.inject._ 
import play.api._ 
import play.api.mvc._ 
import play.api.libs.json._ 
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 
/** 
* 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 { 


    def validate(receivedMsg:JsValue,outChannel:Concurrent.Channel[JsValue], privateChannel:Concurrent.Channel[JsValue],outEnumerator:Enumerator[JsValue],privateEnumerator:Enumerator[JsValue]) = { 

    val user_key = (receivedMsg \ "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"}""") 

      outChannel.push(successMsg) 
      (outEnumerator) 


     } 
     else{ 
      //cache is already set 
      //send error msg to new user 

      val errorMsg = Json.parse("""{"username":"Server","message":"This username is already taken"}""") 



      // val (privateEnumerator,privateChannel) = Concurrent.broadcast[JsValue] 
      privateChannel.push(errorMsg) 

      (privateEnumerator) 


     } 




    } 


val (outEnumerator,outChannel) = Concurrent.broadcast[JsValue]; //public stuff 

    def socket = WebSocket.using[JsValue] { 


    request => { 



    val (privateEnumerator,privateChannel) = Concurrent.broadcast[JsValue] 

    var enumerator = privateEnumerator 
    var ret = 1; 
    val inIteratee: Iteratee[JsValue, Unit] = Iteratee.foreach[JsValue](receivedMsg => { 



    enumerator = validate(receivedMsg,outChannel,privateChannel,outEnumerator,privateEnumerator) 



    }) 

    (inIteratee, enumerator) 
    } 
} 


} 

我是scala和Play webSockets的新手。我正在玩2.5.3。以上情況取決於具體情況,我試圖讓私人頻道或公共頻道的統計員(即針對所有連接的用戶)。但即使它正確返回它,我也無法在這裏得到它(迭代器,枚舉器)。我究竟做錯了什麼?無法獲得Play中的枚舉器的值2.5 websocktes

+0

這一個的第二個答案(http://stackoverflow.com/questions/24576405/broadcasting-messages-in-play-framework-websockets/24628002#24628002)將幫助你。 – pamu

回答

0

本帖子中的第二個答案(Broadcasting messages in Play Framework WebSockets)也是一樣。

創建演員說UserManagerActor誰的唯一目的是管理用戶和維護他們。

UserManagerActor通話廣播。

val (enumerator, channel) = Concurrent.broadcast[String]

channel有助於向所有用戶廣播消息,一旦使用push方法即可。

現在的演員可以在地圖

val users = Map[String, (Enumerator[String],Channel[String])]()

管理用戶的狀態,確保演員被殺一次所有用戶斷開連接。

使用Iteratee知道的是用戶斷開

同時刪除斷開用戶保持地圖管理的大小。