【问题标题】:unable to get the value of enumerator in Play 2.5 websocktes无法在 Play 2.5 websocktes 中获取枚举器的值
【发布时间】:2023-03-28 21:20:01
【问题描述】:
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。以上根据情况,我试图获取私人频道或公共频道的枚举器(即所有连接的用户)。但即使它正确返回它,我也无法在此处获取它(iteratee,enumerator)。我做错了什么?

【问题讨论】:

标签: scala playframework websocket


【解决方案1】:

这篇文章的第二个答案 (Broadcasting messages in Play Framework WebSockets) 做同样的事情。

创建一个角色UserManagerActor,其唯一目的是管理和维护用户。

UserManagerActor 呼叫广播。

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

channel 有助于使用push 方法向所有用户广播消息。

现在actor可以管理地图中用户的状态

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

确保一旦所有用户断开连接,演员就会被杀死。

使用Iteratee 知道用户是否已断开连接

同时删除断开连接的用户,以保持地图的大小易于管理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 2013-04-07
    相关资源
    最近更新 更多