Saltar al contenido principal

Transporte IPC de escritorio

Cuándo usar este modo

Enlace al encabezado

El transporte IPC de escritorio está pensado para arquitecturas tipo Electron/Tauri en las que los runtimes host y remotos viven en procesos o webviews distintos.

Encaja normalmente en:

  • plataformas de extensiones de escritorio;
  • runtimes de plugins aislados del proceso principal de UI;
  • orquestación del shell nativo con políticas IPC explícitas.

Modelo principal

Enlace al encabezado

@omnicajs/vue-remote sigue necesitando el mismo contrato de canal. El IPC es solo el mecanismo de entrega.

Host Renderer (Desktop UI)
-> createReceiver()
-> createEndpoint(fromDesktopIpc(...))
-> call.run(receiver.receive, hostBridge)
Desktop Main Process / IPC Layer
-> routes messages between host and remote peers
-> applies policy, auth/capability checks, and lifecycle rules
Remote Runtime (isolated renderer/webview/process)
-> createEndpoint(fromDesktopIpc(...))
-> expose run/release

Patrón mínimo para el wrapper del endpoint

Enlace al encabezado

Construye un adapter de MessageEndpoint sobre tu puente IPC de escritorio:

import type { MessageEndpoint } from '@remote-ui/rpc'
type DesktopBridge = {
send(channel: string, payload: unknown): void;
on(channel: string, listener: (payload: unknown) => void): void;
off(channel: string, listener: (payload: unknown) => void): void;
close?(): void;
}
export function fromDesktopIpc(
bridge: DesktopBridge,
channel = 'vue-remote:rpc'
): MessageEndpoint {
const listeners = new Set<(event: MessageEvent) => void>()
const onPayload = (payload: unknown) => {
const event = { data: payload } as MessageEvent
for (const listener of listeners) {
listener(event)
}
}
bridge.on(channel, onPayload)
return {
postMessage(message: any) {
bridge.send(channel, message)
},
addEventListener(event, listener) {
if (event === 'message') listeners.add(listener)
},
removeEventListener(event, listener) {
if (event === 'message') listeners.delete(listener)
},
terminate() {
bridge.off(channel, onPayload)
bridge.close?.()
},
}
}

Después usa el flujo estándar del endpoint:

const endpoint = createEndpoint<RemoteApi>(fromDesktopIpc(window.desktopBridge))
await endpoint.call.run(receiver.receive, hostBridge)

Notas sobre Electron y Tauri

Enlace al encabezado

Electron:

  • expón una API IPC estrecha desde preload (contextBridge);
  • mantén contextIsolation: true;
  • evita pasar objetos sin restricciones desde el proceso principal.

Tauri:

  • usa canales de comando/evento como un puente acotado;
  • mantén allowlists explícitas en las capacidades;
  • evita pipes de eventos con comodines amplios para plugins no confiables.

Notas para producción

Enlace al encabezado
  1. Trata los canales IPC como fronteras privilegiadas.
  2. Versiona el protocolo y aplica comprobaciones de compatibilidad.
  3. Añade routing basado en capacidades por sesión de extensión.
  4. Asegúrate de que el teardown cierre los canales y libere las referencias retenidas.

Documentación relacionada

Enlace al encabezado