Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin Ktor拦截器订购相同阶段和覆盖_Kotlin_Ktor - Fatal编程技术网

Kotlin Ktor拦截器订购相同阶段和覆盖

Kotlin Ktor拦截器订购相同阶段和覆盖,kotlin,ktor,Kotlin,Ktor,我目前正在尝试使用功能、管道和拦截器实现以下模式: auth { limit(1) { get { call.respond("Cake1") } } } 在这两个功能中,我都使用以下内容: pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, myCustomPhase) pipeline.intercept(appTokenAuthPhase) 我有以

我目前正在尝试使用功能、管道和拦截器实现以下模式:

auth {
    limit(1) {
        get {
            call.respond("Cake1")
        }
    }
}
在这两个功能中,我都使用以下内容:

pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, myCustomPhase)
pipeline.intercept(appTokenAuthPhase)
我有以下两个问题:

  • 使用PhaseAfter时,顺序错误。应该首先调用Auth,其次调用Limit。为什么限制是第一位的?我怎样才能防止这种情况?注意:它应该始终取决于代码序列,第一个块应该首先执行。由于一些未知的原因,它与PhaseBefore的预期一样工作。但这似乎不一致。这些方法将阶段放置在其他阶段的适当位置,但不对合并执行排序。这是怎么做到的
  • 插入相位之后

    [阶段(“设置”)、阶段(“监控”)、阶段(“功能”)、阶段(“限制”)、阶段(“调用”)、阶段(“回退”)]

    [阶段('Setup')、阶段('Monitoring')、阶段('Features')、阶段('Auth')、阶段('Call')、阶段('Fallback')]

    在前面插入相位

    [阶段('Setup')、阶段('Monitoring')、阶段('Auth')、阶段('Features')、阶段('Call')、阶段('Fallback')]

    [阶段(“设置”)、阶段(“监控”)、阶段(“限制”)、阶段(“功能”)、阶段(“调用”)、阶段(“回退”)]

  • 我想删除阶段拦截器

  • 因此,对于/sub/critical,只应调用速率为(5)的拦截器,而应跳过速率为(100)的拦截器。在当前的体系结构中这可能吗?我看不出有任何方法可以覆盖合并并删除除“Limit”阶段的“last”拦截器之外的所有拦截器。对于儿童时期没有“限制”的所有管道,另一个“限制”应保持不变。其他拦截器(如Auth)应该像往常一样执行。

    我将向您介绍我在第2部分中所做的工作。我不确定它是否性感。基本上,当我使用自定义内容向路由添加新的子级时,我会计算路由中已有多少父级具有相同的选择器。然后我将该数量传递到拦截器中,以便知道当前子对象的嵌套位置

     fun Route.test(
            message: String,
            build: Route.() -> Unit,
        ): Route {
            val testRoute = createChild(SimpleSelector("message"))
            application.feature(SimpleInterceptor).apply {
                interceptPipeline(testRoute, message, testRoute.countSimpleSelectors())
            }
            testRoute.build()
            return testRoute
        }
        
        fun Route.countSimpleSelectors(): Int = 
            (parent?.countSimpleSelectors() ?: 0) +
                if (parent?.selector is SimpleSelector) {
                    1
                } else {
                    0
                }
    
    然后在拦截器中,我将添加与嵌套拦截器一样多的阶段。但我以相反的顺序添加它们,这意味着最后添加的拦截器将首先运行

    fun interceptPipeline(
        pipeline: ApplicationCallPipeline,
        message: String,
        nestingCounter: Int,
    ) {
        pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, Authentication.ChallengePhase)
        val phases = (nestingCounter downTo 0).map {
            simplePhase(it)
        }
        phases.fold(Authentication.ChallengePhase) { old, new ->
            pipeline.insertPhaseAfter(old, new)
            new
        }
        pipeline.intercept(phases.first()) {
            val call = call
            val simpleContext = SimpleContext.from(call)
            TestPipeline().apply {
                val subject = SimpleContext.from(call)
                println("original subject: $message, new subject: ${subject.someMessage}")
                subject.someMessage = message
            }.execute(call, simpleContext)
        }
    }
    
    现在,链中最新添加的拦截器将首先运行。剩下的就是拦截器向管道添加上下文。此上下文可以是您想要的任何内容,因此您可以向上下文添加一个布尔值:isAlreadyHandled。第一个拦截器可以在它完成后翻转它,接下来的拦截器可以忽略管道

    我基于以下几点:

    以及随附的github回购协议:


    我使用了与那里相同的结构,只是添加了计数和上下文。我希望这有点帮助

    你有没有想到这一点?:)我现在也被这个角色困住了2@Josttie不。1号的github问题一直没有解决(只是移动到了他们的内部跟踪器),然后我甚至都不关心2号。Imo ktor更像是一个概念验证框架。不会用它来做任何有成效的事情。但如果你发现了,请随时回答。祝你好运
    fun interceptPipeline(
        pipeline: ApplicationCallPipeline,
        message: String,
        nestingCounter: Int,
    ) {
        pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, Authentication.ChallengePhase)
        val phases = (nestingCounter downTo 0).map {
            simplePhase(it)
        }
        phases.fold(Authentication.ChallengePhase) { old, new ->
            pipeline.insertPhaseAfter(old, new)
            new
        }
        pipeline.intercept(phases.first()) {
            val call = call
            val simpleContext = SimpleContext.from(call)
            TestPipeline().apply {
                val subject = SimpleContext.from(call)
                println("original subject: $message, new subject: ${subject.someMessage}")
                subject.someMessage = message
            }.execute(call, simpleContext)
        }
    }