服务器Scala与Play的响应

时间:2017-07-31 04:27:00

标签: scala playframework websocket

我正在用Scala和Play做我的第一个应用程序!我在聊天室示例中使用的WebSocket就像他们在聊天室示例中所做的那样,到目前为止,我可以向我的服务器发送消息,但我似乎并不明白我可以“处理”我从客户端获取此消息的位置,我也想知道我是否可以将Json Arrays从我的服务器发送到我的客户端:

@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函数从客户端发送消息的。

编辑我想要处理这些消息的方法是将它们作为参数传递给函数,该函数将返回一个字符串或整数数组,我想返回给客户端

1 个答案:

答案 0 :(得分: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()