Volver al inicio

gRPC IPC para escritorios .NET: separando lógica de UI

El artículo describe la arquitectura de una aplicación de escritorio .NET con separación de UI y lógica de negocio vía gRPC e IPC. Backend sin cabeza asegura fiabilidad, cliente delgado — UX. Ejemplos de proto, Rx.NET y ciclo de vida del proceso.

gRPC e IPC en .NET: arquitectura de escritorio confiable sin monolito
Advertisement 728x90

Separando la Interfaz de Usuario y la Lógica de Negocio en Aplicaciones de Escritorio .NET con gRPC e IPC

En aplicaciones de escritorio con WPF o Avalonia UI, la lógica de negocio está fuertemente acoplada al hilo de la interfaz. Los bloqueos en el renderizado o las caídas de XAML detienen todo el sistema: los temporizadores se reinician, las peticiones a la API se interrumpen y se pierde el estado. Esto es crítico para tareas en segundo plano como la gestión de hogares inteligentes, el bloqueo de procesos o los reproductores multimedia.

La solución es dividir en un backend sin interfaz (Servicio Worker) y un cliente ligero (UI). Se comunican mediante gRPC con streaming del lado del servidor, garantizando la independencia de procesos.

Arquitectura: Dos Procesos, Comunicación Segura

Backend (Axorith.Host) — un Servicio Worker de .NET, compilado como WinExe. Responsable de:

Google AdInline article slot
  • Almacenar el estado de la sesión.
  • Temporizadores y orquestación de módulos.
  • Integración con Home Assistant, Spotify, monitorización de procesos ETW.
  • Gestión del navegador mediante Named Pipes.

Consumo en reposo: 20–30 MB de RAM. Se ejecuta de forma autónoma, independiente de la UI.

Frontend (Axorith.Client) en Avalonia UI con ReactiveUI. Solo visualización y entrada. La interfaz puede cerrarse en el Administrador de tareas — el backend sigue funcionando.

Dependencias de capas:

Google AdInline article slot
  • Cliente y Host referencian Axorith.Contracts (proto gRPC).
  • Core compartido para el motor de sesión.
  • Shared para utilidades y código dependiente de la plataforma.
  • Los módulos (plugins) dependen del Sdk.

gRPC con Streaming del Lado del Servidor para Reactividad

gRPC se elige por los contratos protobuf y el streaming. Proto para actualizaciones de configuración:

syntax = "proto3";

package axorith.contracts;

service ModulesService {
    rpc StreamSettingUpdates (StreamSettingUpdatesRequest) returns (stream SettingUpdate);
}

message SettingUpdate {
    string module_instance_id = 1;
    string setting_key = 2;
    SettingProperty property = 3;

    oneof value {
        string string_value = 4;
        bool bool_value = 5;
        int32 int_value = 6;
        double number_value = 7;
        ChoiceList choice_list = 8;
    }
}

En el host: SettingUpdateBroadcaster con Rx.NET Subject. Los cambios en los módulos (por ejemplo, cambio de pista) se envían al stream.

En el cliente: Se abre un stream al inicio, las actualizaciones van al ViewModel. ReactiveUI garantiza el redibujado instantáneo sin retrasos.

Google AdInline article slot

Ventajas sobre el polling:

  • Sin retrasos (push en lugar de polling).
  • Uso eficiente del tráfico.
  • El tipado fuerte de protobuf evita la desincronización.

IPC Seguro en Lugar de TCP

Los puertos locales son vulnerables: conflictos, acceso de virus, ventanas emergentes del firewall. Cambiando a IPC:

| Plataforma | Transporte | ACL |

|-----------|-----------|-----|

| Windows | Named Pipes (ListenNamedPipe) | Solo el usuario actual |

| Linux/macOS | Unix Domain Sockets (ListenUnixSocket) | Permisos de archivo |

El host escribe el endpoint en %AppData%/Axorith/host-info.json. El cliente lee y se conecta. Aislamiento completo de procesos.

Ciclo de Vida y Experiencia de Usuario

Enfoque cliente-primero:

  • Lanzar Client.exe.
  • Verificar host-info.json, iniciar Host automáticamente en segundo plano.
  • Cerrar la ventana — minimizar a la bandeja (modo --tray).
  • Icono en la bandeja para reiniciar/detener Host o restaurar la UI.

Detección de caída de conexión: HTTP/2 Keep-Alive detecta interrupciones del stream. El host envía una notificación del sistema (Windows Toast / D-Bus).

Prueba de resiliencia:

  • Sesión de "trabajo": Spotify reproduciendo, YouTube bloqueado.
  • Cerrar Cliente en el Administrador de tareas.
  • Resultado: backend vivo, la sesión continúa.

Desafíos de Implementación

  • Contratos: Cada cambio requiere regenerar el proto, actualizar ambos lados.
  • Control de versiones: El Interceptor de gRPC verifica x-axorith-version. La discrepancia resulta en FailedPrecondition + actualización automática.
  • Asincronía: Todas las llamadas son basadas en Task, manejando tiempos de espera, errores de red en localhost.

Conclusiones Clave

  • La separación de procesos elimina el punto único de fallo en el hilo de la UI.
  • El streaming de gRPC + Rx.NET proporciona una UI reactiva sin polling.
  • IPC (Named Pipes/UDS) garantiza seguridad sin puertos.
  • La experiencia de usuario cliente-primero oculta la complejidad al usuario.
  • Adecuado para aplicaciones 24/7 con gestión del sistema.

— Editorial Team

Advertisement 728x90

Leer después