es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Kotlin Flow y Websockets con arquitectura limpia en Android

Recientemente, nuestro equipo intentó implementar websockets. Pensamos fácilmente en usar Rx cuando escuchamos eventos, pero me pregunté cómo hacerlo sin él. Así que probamos el famoso Kotlin Flow, pero no sé si nuestra implementación es correcta.

La arquitectura de nuestra aplicación está dividida en cuatro capas:
– Servicio: emite y recibe eventos del socket.
– Repositorio: filtra, mapea, transforma, etc.
– ViewModel: populan los LiveDatas.
– Actividad: observa los cambios y actualiza la interfaz de usuario.

Por lo tanto, escuchamos los eventos recibidos en el servicio de la siguiente manera:

fun listenMessages(): Flow<><message>> = channelFlow {
    socket.on("NewMessage") { args ->
        val message = gson.fromJson(args[0].toString(), ...)
        trySend(message)
    }
    awaitClose()
}

Utilizamos la corrutina channelFlow para enviar al consumidor cuando se recibe un evento con trySend, y mantenemos este Flow vivo usando awaitClose.

El repositorio realiza cierta lógica después de recibir el Flow y lo envía de vuelta al ViewModel:

fun getMessages(): Flow<><message>> {
    return service.listenMessages()
            .filter { ... }
            .map { ... }
}

Luego, el ViewModel lanza las corrutinas y actualiza el LiveData al recolectar el Flow:

fun getMessages() {
    viewModelScope.launch(context = Dispatcher.IO) {
        repository.getMessages()
                .collect {
                    messagesLiveData.postValue(it)
                }
    }
}

Esto funciona bien, sin embargo, esto plantea algunas preguntas:
– ¿Es esta la implementación correcta?
– ¿Cuando necesitamos escuchar constantemente, es channelFlow la elección correcta?
– En este caso, ¿deberíamos usar canales clásicos en lugar de Flow (caliente vs frío)?

Gracias de antemano por sus consejos.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La implementación parece correcta y sigue el enfoque recomendado para usar Flow.

    channelFlow es una buena elección para escuchar eventos constantemente, ya que proporciona una forma conveniente de emitir eventos tan pronto como se reciben.

    Si bien Channel también se podría usar en este escenario, sería menos eficiente ya que requiere un manejo manual más minucioso de los eventos. Además, Channel puede tener más errores que Flow, ya que requiere el uso de close() para evitar fugas de memoria.

    En general, usar Flow en lugar de RxJava para este tipo de escenario es una excelente opción, ya que ayuda a simplificar el código y reducir la cantidad de código repetitivo necesario para gestionar flujos de eventos.

Comments are closed.