【问题标题】:Play Framework - Upgrade to Web socket manuallyPlay Framework - 手动升级到 Web socket
【发布时间】:2023-03-25 20:08:01
【问题描述】:

升级到 web socket 是在 play 框架中抽象出来的。如何手动实现?

我使用 play 框架创建了一个 Web 套接字应用程序。 我可以在 Web 套接字客户端和服务器(我创建的)之间建立连接 但是升级到 web socket 已经被 play-framework 抽象出来了。

def chatSystem(): WebSocket = WebSocket.acceptOrResult[String, String] { request =>
    Future.successful{
      AuthenticationService.doBasicAuthentication(request.headers) match {
        case Results.Ok => Right(ActorFlow.actorRef { out => ChatServiceActor.props(out) })
        case _ => Left(Unauthorized)
      }
    }
  }

URL : ws://localhost:9000/chatSystem/test123

在建立连接之前我需要做以下事情,

如果 Websocket-server 无法识别 URL 路径中的 userId,它应该发送一个状态为 404 的 HTTP 响应并中止 WebSocket 连接

如果 Websocket-server 不同意使用客户端提供的子协议之一,它必须完成 Web Socket 握手并返回不带 Sec-WebSocket-Protocol 标头的响应,然后立即关闭 WebSocket 连接。

我不确定如何手动实现逻辑,以便向客户端发送升级响应,然后建立 Web 套接字 连接。

【问题讨论】:

    标签: scala websocket playframework


    【解决方案1】:

    遗憾的是,我认为这是不可能的,我能够检测到 WebSocketHandler,并且 play 期望实现路由的方法返回 Handler,所以理论上,如果可以的话构建一个返回Handler 的方法,该方法将RequestHeader 转换为另一个Handler(如trait CustomHandler extends (RequestHeader => Handler) with Handler),然后,您将能够创建一个实例来检查Web 套接字连接是否应该是成立。

    但是,如果你这样做,你会在发出请求时遇到异常,希望有一个我遗漏的关键细节,我建议在他们的 github 上打开一张票:

    我的堆栈跟踪是:

    akka.http.impl.util.One2OneBidiFlow$OutputTruncationException: Inner flow was completed without producing result elements for 1 outstanding elements
        at akka.http.impl.util.One2OneBidiFlow$OutputTruncationException$.apply(One2OneBidiFlow.scala:22)
        at akka.http.impl.util.One2OneBidiFlow$OutputTruncationException$.apply(One2OneBidiFlow.scala:22)
        at akka.http.impl.util.One2OneBidiFlow$One2OneBidi$$anon$1$$anon$4.onUpstreamFinish(One2OneBidiFlow.scala:97)
        at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:504)
        at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
        at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:588)
        at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:472)
        at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:563)
        at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:745)
        at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:760)
        at akka.actor.Actor.aroundReceive(Actor.scala:517)
        at akka.actor.Actor.aroundReceive$(Actor.scala:515)
        at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:670)
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:588)
        at akka.actor.ActorCell.invoke(ActorCell.scala:557)
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:258)
        at akka.dispatch.Mailbox.run(Mailbox.scala:225)
        at akka.dispatch.Mailbox.exec(Mailbox.scala:235)
        at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
        at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
        at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
        at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
    akka.http.impl.util.One2OneBidiFlow$OutputTruncationException: Inner flow was completed without producing result elements for 1 outstanding elements
        at akka.http.impl.util.One2OneBidiFlow$OutputTruncationException$.apply(One2OneBidiFlow.scala:22)
        at akka.http.impl.util.One2OneBidiFlow$OutputTruncationException$.apply(One2OneBidiFlow.scala:22)
        at akka.http.impl.util.One2OneBidiFlow$One2OneBidi$$anon$1$$anon$4.onUpstreamFinish(One2OneBidiFlow.scala:97)
        at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:504)
        at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
        at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:588)
        at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:472)
        at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:563)
        at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:745)
        at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:760)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2012-10-31
      相关资源
      最近更新 更多