I am trying to create a Ktor Server which currently runs on localhost. When i run only one instance of the server on terminal it is working fine, but when i open a new tab on terminal and run another instance of the same server i get this Warning/Error:
Exception in thread "main" java.net.BindException: Address already in use
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:461)
at sun.nio.ch.Net.bind(Net.java:453)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:222)
at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:134)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:562)
at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:506)
at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:491)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:973)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:260)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:356)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.ktor.server.netty.EventLoopGroupProxy$Companion$create$factory$1$1.run(NettyApplicationEngine.kt:241)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
This happens because the server is using the port which is already in use.
What i am trying to achieve, is that the server should generate a unique port number for the second instance automatically. I am not sure how to do this on Ktor.
This is the current configuration of my server:
fun main() {
val env = applicationEngineEnvironment {
module {
main()
}
connector {
host = "localhost"
port = 8080
}
}
embeddedServer(Netty, env).start(true)
}
You can use ServerSocket to automatically allocate a port number and close that socket. Here is an example:
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.application.*
import io.ktor.response.*
import io.ktor.routing.*
import java.net.ServerSocket
fun main(args: Array<String>) {
embeddedServer(Netty, port = getFreePort()) {
routing {
get("/") {
call.respondText { "Hello" }
}
}
}.start()
}
fun getFreePort(): Int {
val socket = ServerSocket(0)
val port = socket.localPort
socket.close()
return port
}
Also, there is an up for grabs feature request to allocate a random port number out of the box.