diff --git a/android/app/src/main/java/io/picoclaw/android/di/AppModule.kt b/android/app/src/main/java/io/picoclaw/android/di/AppModule.kt index c2f8e27ed..3a0ff7059 100644 --- a/android/app/src/main/java/io/picoclaw/android/di/AppModule.kt +++ b/android/app/src/main/java/io/picoclaw/android/di/AppModule.kt @@ -23,6 +23,7 @@ import okhttp3.OkHttpClient import org.koin.android.ext.koin.androidContext import org.koin.core.module.dsl.viewModel import org.koin.dsl.module +import java.util.UUID import java.util.concurrent.TimeUnit val appModule = module { @@ -52,7 +53,13 @@ val appModule = module { } // WebSocketClient - single { WebSocketClient(get(), get()) } + single { + val prefs = androidContext().getSharedPreferences("picoclaw", android.content.Context.MODE_PRIVATE) + val clientId = prefs.getString("client_id", null) ?: UUID.randomUUID().toString().also { + prefs.edit().putString("client_id", it).apply() + } + WebSocketClient(get(), get(), clientId) + } // ImageFileStorage single { ImageFileStorage(androidContext()) } diff --git a/android/core/data/src/main/java/io/picoclaw/android/core/data/remote/WebSocketClient.kt b/android/core/data/src/main/java/io/picoclaw/android/core/data/remote/WebSocketClient.kt index eac1c0a5f..7df89a654 100644 --- a/android/core/data/src/main/java/io/picoclaw/android/core/data/remote/WebSocketClient.kt +++ b/android/core/data/src/main/java/io/picoclaw/android/core/data/remote/WebSocketClient.kt @@ -25,7 +25,8 @@ import kotlinx.serialization.json.Json class WebSocketClient( private val client: HttpClient, - private val scope: CoroutineScope + private val scope: CoroutineScope, + private val clientId: String ) { private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED) @@ -47,7 +48,8 @@ class WebSocketClient( while (isActive) { try { _connectionState.value = ConnectionState.CONNECTING - client.webSocket(wsUrl) { + val url = "$wsUrl?client_id=$clientId" + client.webSocket(url) { session = this _connectionState.value = ConnectionState.CONNECTED retryDelay = INITIAL_DELAY diff --git a/pkg/channels/websocket.go b/pkg/channels/websocket.go index 1a50f6b16..8dfbcb8c3 100644 --- a/pkg/channels/websocket.go +++ b/pkg/channels/websocket.go @@ -166,7 +166,10 @@ func (c *WebSocketChannel) handleWS(w http.ResponseWriter, r *http.Request) { return } - clientID := uuid.New().String() + clientID := r.URL.Query().Get("client_id") + if clientID == "" { + clientID = uuid.New().String() + } logger.InfoCF("websocket", "New WebSocket connection", map[string]interface{}{ "client_id": clientID, @@ -176,6 +179,10 @@ func (c *WebSocketChannel) handleWS(w http.ResponseWriter, r *http.Request) { chatID := fmt.Sprintf("ws:%s", clientID) c.mu.Lock() + if oldConn, ok := c.chatConns[chatID]; ok { + delete(c.clients, oldConn) + oldConn.Close() + } c.clients[conn] = clientID c.chatConns[chatID] = conn c.mu.Unlock()