【问题标题】:Response from Server Scala with Play来自服务器 Scala 与 Play 的响应
【发布时间】:2017-07-31 04:26:59
【问题描述】:

我正在使用 Scala 和 Play 做我的第一个应用程序!我在聊天室示例中完全使用 WebSocket 的地方,到目前为止,我可以将消息发送到我的服务器,但我似乎不明白在哪里可以“处理”我从客户端获得的这些消息,我也想知道我是否可以将 Json 数组从我的服务器发送到我的客户端:

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

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

【问题讨论】:

    标签: scala playframework websocket


    【解决方案1】:

    您需要做的就是在您的源和接收器之间添加一个流阶段,该阶段可以存储在数据库中并向客户端返回一些其他消息。

    以下是解决上述问题的方法:

    在此处对收到的消息做任何你想做的事情。

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-26
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2021-12-15
      • 2013-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多