feat: connect to server on app launch

This commit is contained in:
Fritz Heiden 2025-04-01 19:11:03 +02:00
parent 645f8e2f04
commit 7471168a21
2 changed files with 33 additions and 11 deletions

View File

@ -23,6 +23,7 @@ import com.example.tvcontroller.ui.theme.TVControllerTheme
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.lifecycle.lifecycleScope
import com.example.tvcontroller.services.BluetoothService import com.example.tvcontroller.services.BluetoothService
import com.example.tvcontroller.services.CameraService import com.example.tvcontroller.services.CameraService
import com.example.tvcontroller.services.ControllerService import com.example.tvcontroller.services.ControllerService
@ -30,6 +31,8 @@ import com.example.tvcontroller.services.DeviceService
import com.example.tvcontroller.ui.views.CameraView import com.example.tvcontroller.ui.views.CameraView
import com.example.tvcontroller.ui.views.RemoteView import com.example.tvcontroller.ui.views.RemoteView
import com.example.tvcontroller.ui.views.SettingsView import com.example.tvcontroller.ui.views.SettingsView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
const val TAG = "MainActivity" const val TAG = "MainActivity"
@ -47,6 +50,10 @@ class MainActivity : ComponentActivity() {
cameraService = CameraService(this.applicationContext) cameraService = CameraService(this.applicationContext)
controllerService = ControllerService(this.applicationContext, bluetoothService) controllerService = ControllerService(this.applicationContext, bluetoothService)
checkPermissions() checkPermissions()
lifecycleScope.launch(Dispatchers.IO) {
deviceService.initialize()
}
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
TVControllerTheme { TVControllerTheme {

View File

@ -10,10 +10,13 @@ import io.ktor.client.call.body
import io.ktor.client.plugins.cookies.HttpCookies import io.ktor.client.plugins.cookies.HttpCookies
import io.ktor.client.plugins.websocket.WebSockets import io.ktor.client.plugins.websocket.WebSockets
import io.ktor.client.plugins.websocket.webSocket import io.ktor.client.plugins.websocket.webSocket
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.cookie
import io.ktor.client.request.headers import io.ktor.client.request.headers
import io.ktor.client.request.request import io.ktor.client.request.request
import io.ktor.client.request.setBody import io.ktor.client.request.setBody
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse
import io.ktor.http.Cookie
import io.ktor.http.HttpMethod import io.ktor.http.HttpMethod
import io.ktor.websocket.Frame import io.ktor.websocket.Frame
import io.ktor.websocket.readText import io.ktor.websocket.readText
@ -25,15 +28,18 @@ private const val TAG = "DeviceService"
class DeviceService(private val context: Context) { class DeviceService(private val context: Context) {
private var client = HttpClient(CIO) { private var client = HttpClient(CIO) {
install(HttpCookies)
install(WebSockets) install(WebSockets)
} }
private var serverAddress: String = "" private var serverAddress: String = ""
private var token: String = "" private var token: String = ""
private var deviceId: String = "" private var deviceId: String = ""
init { suspend fun initialize() {
loadPreferences() loadPreferences()
if (token.isEmpty()) return
getIntegration()?.let {
connect()
}
} }
suspend fun registerIntegration(name: String, code: String) { suspend fun registerIntegration(name: String, code: String) {
@ -44,13 +50,15 @@ class DeviceService(private val context: Context) {
token = "" token = ""
deviceId = "" deviceId = ""
try { try {
val response: HttpResponse = client.request("http://$serverAddress/api/integrations/register") { val response: HttpResponse =
method = HttpMethod.Post client.request("http://$serverAddress/api/integrations/register") {
setBody(requestJson.toString()) method = HttpMethod.Post
headers { setBody(requestJson.toString())
append("Content-Type", "application/json") headers {
append("Content-Type", "application/json")
}
cookie(name = "token", value = token)
} }
}
val body: String = response.body() val body: String = response.body()
val responseJson = JSONObject(body) val responseJson = JSONObject(body)
@ -78,6 +86,7 @@ class DeviceService(private val context: Context) {
headers { headers {
append("Authorization", "Bearer $token") append("Authorization", "Bearer $token")
} }
cookie(name = "token", value = token)
} }
val body: String = response.body() val body: String = response.body()
@ -120,11 +129,17 @@ class DeviceService(private val context: Context) {
fun connect() { fun connect() {
Log.i(TAG, "Connecting to websocket at $serverAddress") Log.i(TAG, "Connecting to websocket at $serverAddress")
runBlocking { runBlocking {
// split server address into host and port
val (host, port) = serverAddress.split(":") val (host, port) = serverAddress.split(":")
// if no port is specified, assume 80
val portInt = if (port.isEmpty()) 80 else port.toInt() val portInt = if (port.isEmpty()) 80 else port.toInt()
client.webSocket(method = HttpMethod.Get, host = host, port = portInt, path = "/ws") { client.webSocket(
method = HttpMethod.Get,
host = host,
port = portInt,
path = "/ws",
request = {
cookie(name = "token", value = token)
}
) {
Log.i(TAG, "Listening for incoming websocket messages") Log.i(TAG, "Listening for incoming websocket messages")
while (true) { while (true) {
val frame = incoming.receive() val frame = incoming.receive()