Ktor 3.x:如何在CoroutineScope扩展函数中使用configure配置?
问题
我正在使用Ktor 3.x,希望通过CoroutineScope扩展函数启动嵌入式服务器,同时传入自定义的configure配置脚本。
从普通embeddedServer函数签名可见,存在支持传入configure: TConfiguration.() -> Unit = {}的重载:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> embeddedServer( factory: ApplicationEngineFactory<TEngine, TConfiguration>, environment: ApplicationEnvironment = applicationEnvironment(), configure: TConfiguration.() -> Unit = {}, module: Application.() -> Unit = {} ): EmbeddedServer<TEngine, TConfiguration>
但观察CoroutineScope的embeddedServer扩展函数签名,并未提供传入configure代码块的参数:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer( factory: ApplicationEngineFactory<TEngine, TConfiguration>, vararg connectors: EngineConnectorConfig = arrayOf(), watchPaths: List<String> = listOf(WORKING_DIRECTORY_PATH), parentCoroutineContext: CoroutineContext = EmptyCoroutineContext, module: Application.() -> Unit ): EmbeddedServer<TEngine, TConfiguration>
以及:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer( factory: ApplicationEngineFactory<TEngine, TConfiguration>, port: Int = 80, host: String = "0.0.0.0", watchPaths: List<String> = listOf(WORKING_DIRECTORY_PATH), parentCoroutineContext: CoroutineContext = EmptyCoroutineContext, module: Application.() -> Unit ): EmbeddedServer<TEngine, TConfiguration>
请问使用CoroutineScope扩展函数时,如何实现configure配置功能?
解决方案
可以通过以下几种方式实现需求:
方法1:手动构建环境并关联CoroutineScope
直接调用带configure参数的基础embeddedServer函数,再将服务器启动在指定的CoroutineScope上下文中:
val scope = CoroutineScope(Dispatchers.IO) val server = embeddedServer( factory = Netty, environment = applicationEnvironment { connector { port = 8080 host = "0.0.0.0" } watchPaths = listOf(WORKING_DIRECTORY_PATH) }, configure = { // 自定义配置逻辑示例 connectionGroupSize = 8 workerGroupSize = 16 requestTimeout = 30.seconds }, module = { routing { get("/") { call.respondText("Hello World") } } } ) // 在指定CoroutineScope中启动服务器 scope.launch { server.start(wait = true) }
方法2:自定义CoroutineScope扩展函数
自己实现带configure参数的CoroutineScope扩展,复用官方扩展的便捷性:
fun <TEngine : ApplicationEngine, TConfiguration : ApplicationEngine.Configuration> CoroutineScope.embeddedServer( factory: ApplicationEngineFactory<TEngine, TConfiguration>, port: Int = 80, host: String = "0.0.0.0", watchPaths: List<String> = listOf(WORKING_DIRECTORY_PATH), parentCoroutineContext: CoroutineContext = EmptyCoroutineContext, configure: TConfiguration.() -> Unit = {}, module: Application.() -> Unit ): EmbeddedServer<TEngine, TConfiguration> { val environment = applicationEnvironment { connector { this.port = port this.host = host } this.watchPaths = watchPaths } val server = embeddedServer(factory, environment, configure, module) server.engine.parentCoroutineContext = this.coroutineContext + parentCoroutineContext return server }
使用方式和官方扩展一致,同时支持传入configure:
val scope = CoroutineScope(Dispatchers.Default) scope.embeddedServer( factory = Netty, port = 8080, configure = { callGroupSize = 32 }, module = { // 应用模块配置 } ).start(wait = true)
方法3:启动后修改配置(限部分场景)
如果配置不需要在启动前生效,可以获取EmbeddedServer实例后直接修改其配置:
val scope = CoroutineScope(Dispatchers.IO) val server = scope.embeddedServer( factory = Netty, port = 8080, module = { /* 模块配置 */ } ) // 修改服务器配置 server.configuration.apply { workerGroupSize = 16 } server.start(wait = true)
注意:部分引擎的核心配置在启动后修改可能无效,建议优先使用前两种方法。
内容的提问来源于stack exchange,提问作者tajacks
相关产品推荐
相关产品推荐

