2017-07-31 66 views
1

我正在做Scala和Play的第一個應用程序!在我使用WebSocket的時候,就像他們在聊天室示例中一樣,到目前爲止,我可以向我的服務器發送消息,但我似乎無法理解我可以「處理」從客戶那裏獲得的這些消息,我也想知道如果我可以從我的服務器發送JSON數組我的客戶:服務器Scala與Play的響應

@Singleton 
class HomeController @Inject()(cc: ControllerComponents) 
           (implicit actorSystem: ActorSystem, 
           mat: Materializer, 
           executionContext: ExecutionContext) 
           extends AbstractController(cc) { 

    private type WSMessage = String 

    private val logger = Logger(getClass) 

    private implicit val logging = Logging(actorSystem.eventStream, logger.underlyingLogger.getName) 

    // chat room many clients -> merge hub -> broadcasthub -> many clients 
    private val (chatSink, chatSource) = { 
    // Don't log MergeHub$ProducerFailed as error if the client disconnects. 
    // recoverWithRetries -1 is essentially "recoverWith" 
    val source = MergeHub.source[WSMessage] 
     .log("source") 
     .recoverWithRetries(-1, { case _: Exception ⇒ Source.empty }) 

    val sink = BroadcastHub.sink[WSMessage] 
    source.toMat(sink)(Keep.both).run() 
    } 

    private val userFlow: Flow[WSMessage, WSMessage, _] = { 
    Flow.fromSinkAndSource(chatSink, chatSource) 
    } 

    def index: Action[AnyContent] = Action { implicit request: RequestHeader => 
    val webSocketUrl = routes.HomeController.chat().webSocketURL() 
    logger.info(s"index: ") 
    Ok(views.html.index(webSocketUrl)) 
    } 

    def chat(): WebSocket = { 
    WebSocket.acceptOrResult[WSMessage, WSMessage] { 
     case rh if sameOriginCheck(rh) => 
     Future.successful(userFlow).map { flow => 
      Right(flow) 
     }.recover { 
      case e: Exception => 
      val msg = "Cannot create websocket" 
      logger.error(msg, e) 
      val result = InternalServerError(msg) 
      Left(result) 
     } 

     case rejected => 
     logger.error(s"Request ${rejected} failed same origin check") 
     Future.successful { 
      Left(Forbidden("forbidden")) 
     } 
    } 
    } 

} 

順便說一句,我通過jQuery函數發送從我的客戶端的消息。

編輯我要處理這個消息的方法是將它們作爲參數傳遞給函數,該函數將返回字符串或整數數組,我要返回給客戶端

回答

0

所有你需要的要做的就是在你的源代碼和源代碼之間添加一個流程階段,它可以存儲在數據庫中,並返回一些其他消息給客戶端。

這裏是你如何解決上述問題:

做任何你想要在這裏收到的消息。

val flow = Flow[WSMessage].map { element => 
    println(s"Message: $element") 
    element 
} 

注意,在數據庫持久的消息,您很可能希望使用異步階段,大致爲:

val flow = Flow[WSMessage].mapAsync(parallelism) { element => 
    println(s"Message: $element") 
    // assuming DB.write() returns a Future[Unit] 
    DB.write(element).map(_ => element) 
} 

最後,你需要將流動舞臺添加到流管道。

source.via(flow).toMat(sink)(Keep.both).run()