Scala 如何制作“WebSocketDirections.handleWebSocketMessages”指令的一个版本来公开具体化的值?

Scala 如何制作“WebSocketDirections.handleWebSocketMessages”指令的一个版本来公开具体化的值?,scala,akka-http,Scala,Akka Http,在我看来,akka http库提供的处理web套接字消息的指令是有限的。 如果无法访问图形物化时它们产生的物化值,那么akka stream API提供的大多数阶段都是无用的。如果无法访问它,我们将被限制在几个不重要的阶段,这些阶段对于大多数真实世界的用例来说是不够的。 当前访问传递给handleWebSocketMessages的流图的物化值的方法既复杂又麻烦 因此,为了更好地支持web套接字,必须有一个提取物化值的指令。签名应该是这样的: def handleWebSocketMessage

在我看来,akka http库提供的处理web套接字消息的指令是有限的。 如果无法访问图形物化时它们产生的物化值,那么akka stream API提供的大多数阶段都是无用的。如果无法访问它,我们将被限制在几个不重要的阶段,这些阶段对于大多数真实世界的用例来说是不够的。 当前访问传递给
handleWebSocketMessages
的流图的物化值的方法既复杂又麻烦

因此,为了更好地支持web套接字,必须有一个提取物化值的指令。签名应该是这样的:

def handleWebSocketMessages[Mat](handler: Flow[Message, Message, Mat])(f: Mat => Unit): Route

问题是,如何实现它?

这是我能够实现的实现。尽管它工作得很好,但我相信它可以改进很多。所以,我不认为这是最好的答案。 可以改进的一点是效率。我用来提取物化值的图对每个新的web套接字连接都进行了解释,我认为这是可以避免的

def handleWebSocketMessagesMat[Mat](handler: Flow[Message, Message, Mat])(f: Mat => Unit): Route = {
    def sinkFactory(materializedValue: Mat): Future[Sink[Mat, Future[Done]]] = {
        try {
            f(materializedValue)
            Future.successful(Sink.ignore)

        } catch {
            case NonFatal(e) => Future.failed(e)
        }
    }
    val graph = GraphDSL.create(handler) {
        implicit builder =>
            handlerShape =>
                import GraphDSL.Implicits._

                builder.materializedValue ~> Sink.lazyInit(sinkFactory, null)
                FlowShape[Message, Message](handlerShape.in, handlerShape.out)
    }
    handleWebSocketMessages(Flow.fromGraph(graph))
}

欢迎任何改进。

这是我能够实现的实现。尽管它工作得很好,但我相信它可以改进很多。所以,我不认为这是最好的答案。 可以改进的一点是效率。我用来提取物化值的图对每个新的web套接字连接都进行了解释,我认为这是可以避免的

def handleWebSocketMessagesMat[Mat](handler: Flow[Message, Message, Mat])(f: Mat => Unit): Route = {
    def sinkFactory(materializedValue: Mat): Future[Sink[Mat, Future[Done]]] = {
        try {
            f(materializedValue)
            Future.successful(Sink.ignore)

        } catch {
            case NonFatal(e) => Future.failed(e)
        }
    }
    val graph = GraphDSL.create(handler) {
        implicit builder =>
            handlerShape =>
                import GraphDSL.Implicits._

                builder.materializedValue ~> Sink.lazyInit(sinkFactory, null)
                FlowShape[Message, Message](handlerShape.in, handlerShape.out)
    }
    handleWebSocketMessages(Flow.fromGraph(graph))
}
任何改进都是值得欢迎的