I'm new to Ktor so please bear with me if this question seems a bit silly. I have tried many approaches that I was able to have googled but none of them worked for me.
My goal was to launch a normal activity and host an HTTP server in it with Ktor and let it be able to respond to client requests. When I started a Ktor server from a command line like below it did work and I could see the response from a local browser when I started the emulator:
private suspend fun startServer() = withContext(Dispatchers.IO) {
embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
.start(wait = true)
}
suspend fun main() {
startServer()
readln()
}
However when I attempted to start a Ktor server from an activity, I was never able to get a response:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CoroutineScope(Dispatchers.IO).launch {
embeddedServer(Netty, 8080, host = "127.0.0.1") {
install(ContentNegotiation) {
gson {}
}
routing {
get("/") {
call.respond(mapOf("message" to "Hello world"))
}
}
}.start(wait = true)
}
In my AndroidManifest I did have the following line in place:
<uses-permission android:name="android.permission.INTERNET"/>
But when I attempted to access http://127.0.0.1:8080/ from the host PC, ERR_CONNECTION_REFUSED was the error I received.
These were the messages in the logcat:
I java.io.FileNotFoundException: /proc/sys/net/core/somaxconn: open failed: EACCES (Permission denied)
I at libcore.io.IoBridge.open(IoBridge.java:492)
I at java.io.FileInputStream.<init>(FileInputStream.java:160)
I at java.io.FileReader.<init>(FileReader.java:72)
I at io.netty.util.NetUtil$SoMaxConnAction.run(NetUtil.java:170)
W type=1400 audit(0.0:818): avc: denied { read } for name="somaxconn" dev="proc" ino=29801 scontext=u:r:untrusted_app:s0:c123,c256,c512,c768 tcontext=u:object_r:proc_net:s0 tclass=file permissive=0 app=com.example.androidktorserverdemo
I at io.netty.util.NetUtil$SoMaxConnAction.run(NetUtil.java:155)
I at java.security.AccessController.doPrivileged(AccessController.java:43)
I at io.netty.util.NetUtil.<clinit>(NetUtil.java:152)
I at io.netty.util.internal.MacAddressUtil.bestAvailableMac(MacAddressUtil.java:50)
I at io.netty.util.internal.MacAddressUtil.defaultMachineId(MacAddressUtil.java:137)
I at io.netty.channel.DefaultChannelId.<clinit>(DefaultChannelId.java:99)
I at io.netty.channel.DefaultChannelId.newInstance(DefaultChannelId.java:55)
I at io.netty.channel.AbstractChannel.newId(AbstractChannel.java:113)
I at io.netty.channel.AbstractChannel.<init>(AbstractChannel.java:73)
I at io.netty.channel.nio.AbstractNioChannel.<init>(AbstractNioChannel.java:80)
I at io.netty.channel.nio.AbstractNioMessageChannel.<init>(AbstractNioMessageChannel.java:42)
I at io.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:96)
I at io.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:89)
I at io.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:82)
I at io.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:75)
I at java.lang.reflect.Constructor.newInstance0(Native Method)
I at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
I at io.netty.channel.ReflectiveChannelFactory.newChannel(ReflectiveChannelFactory.java:44)
I at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:310)
I at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:272)
I at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:268)
I at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:253)
I at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:216)
I at com.example.androidktorserverdemo.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:41)
I at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
I at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
I at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
I at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
I at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
I at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
I at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
I at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
I Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
I at libcore.io.Linux.open(Native Method)
I at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
I at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
I at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
I at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542)
I at libcore.io.IoBridge.open(IoBridge.java:478)
I ... 35 common frames omitted
I 09:24:07.457 [DefaultDispatcher-worker-1] DEBUG io.netty.util.internal.ThreadLocalRandom - -Dio.netty.initialSeedUniquifier: 0x6bba82a7aeed8931
I 09:24:07.458 [DefaultDispatcher-worker-1] WARN io.netty.util.internal.MacAddressUtil - Failed to find a usable hardware address from the network interfaces; using random bytes: 06:a8:d6:c2:9a:7f:da:c5
I 09:24:07.459 [DefaultDispatcher-worker-1] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 06:a8:d6:c2:9a:7f:da:c5 (auto-detected)
I 09:24:07.472 [DefaultDispatcher-worker-1] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
I 09:24:07.472 [DefaultDispatcher-worker-1] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
I 09:24:07.501 [DefaultDispatcher-worker-1] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: unpooled
I 09:24:07.502 [DefaultDispatcher-worker-1] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
I 09:24:07.517 [DefaultDispatcher-worker-1] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
I 09:24:07.577 [DefaultDispatcher-worker-3] INFO ktor.application - Responding at http://127.0.0.1:8080
Any suggestions on what I might have done wrong? Thank you very much.