2017-07-31 62 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()