-
Notifications
You must be signed in to change notification settings - Fork 5
/
MainActivity.kt
100 lines (85 loc) · 3.37 KB
/
MainActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package com.example.ktorwsissue
import android.os.Build
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import io.ktor.application.call
import io.ktor.application.install
import io.ktor.features.CallLogging
import io.ktor.http.ContentType
import io.ktor.http.cio.websocket.FrameType
import io.ktor.http.cio.websocket.close
import io.ktor.http.cio.websocket.readBytes
import io.ktor.http.cio.websocket.send
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
import io.ktor.websocket.WebSockets
import io.ktor.websocket.webSocket
import java.net.NetworkInterface
import java.nio.charset.Charset
import java.util.logging.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private val coroutineContext = Dispatchers.IO
private val logger = Logger.getLogger("KtorServer")
private val server by lazy {
embeddedServer(Netty, 13276, watchPaths = emptyList()) {
install(WebSockets)
install(CallLogging)
routing {
get("/") {
call.respondText("All good here in ${Build.MODEL}", ContentType.Text.Plain)
}
webSocket("/ws") {
logger.info("Sending message to client...")
send("foo")
val receivedMessage = incoming.receive()
val messageFormatted = if (receivedMessage.frameType == FrameType.TEXT) {
receivedMessage.readBytes().toString(Charset.defaultCharset())
} else {
"<non-text frame>"
}
logger.info("Got message from client: $messageFormatted")
logger.info("Closing connection...")
close()
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
CoroutineScope(coroutineContext).launch {
logger.info("Starting server...")
server.start(wait = true)
}
findViewById<TextView>(R.id.serverStatusText).text = getString(R.string.serverStartedMessage)
val localIpAddress = getIpAddressInLocalNetwork()
if (localIpAddress != null) {
findViewById<TextView>(R.id.ipAddressText).text =
getString(R.string.localIpAddressMessage, localIpAddress)
}
}
override fun onDestroy() {
logger.info("Stopping server")
server.stop(1_000, 2_000)
super.onDestroy()
}
private fun getIpAddressInLocalNetwork(): String? {
val networkInterfaces = NetworkInterface.getNetworkInterfaces().iterator().asSequence()
val localAddresses = networkInterfaces.flatMap {
it.inetAddresses.asSequence()
.filter { inetAddress ->
inetAddress.isSiteLocalAddress && !inetAddress.hostAddress.contains(":") &&
inetAddress.hostAddress != "127.0.0.1"
}
.map { inetAddress -> inetAddress.hostAddress }
}
return localAddresses.firstOrNull()
}
}