Mensajería nativa

Las extensiones pueden intercambiar mensajes con aplicaciones nativas por medio de una API similar a las otras APIs de paso de mensajes. Las aplicaciones nativas que admiten esta función deben registrar un host de mensajería nativa que pueda comunicarse con la extensión. Chrome inicia el host en un proceso separado y se comunica con él mediante flujos de entrada y salida estándar.

Host de mensajería nativa

Para registrar un host de mensajería nativa, la aplicación debe guardar un archivo que defina la configuración del host de mensajería nativa.

A continuación, se muestra un ejemplo del archivo:

{
  "name": "com.my_company.my_application",
  "description": "My Application",
  "path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe",
  "type": "stdio",
  "allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
}

El archivo de manifiesto del host de mensajería nativa debe tener un formato JSON válido y contener los siguientes campos:

name
Es el nombre del host de mensajería nativa. Los clientes pasan esta cadena a runtime.connectNative() o runtime.sendNativeMessage(). Solo puede contener caracteres alfanuméricos en minúscula, guiones bajos y puntos. El nombre no puede empezar ni terminar con un punto, y otro punto no puede estar seguido de otro.
description
Descripción breve de la aplicación
path
Ruta de acceso al objeto binario del host de la mensajería nativa. En Linux y macOS, la ruta debe ser absoluta. En Windows, puede estar relacionado con el directorio que contiene el archivo de manifiesto. El proceso del host se inicia con el directorio actual configurado en el directorio que contiene el objeto binario del host. Por ejemplo, si este parámetro se establece en C:\Application\nm_host.exe, se iniciará con el directorio actual `C:\Application`.
type
Es el tipo de interfaz que se usa para comunicarse con el host de mensajería nativa. Este parámetro tiene un valor posible: stdio. Indica que Chrome debe usar stdin y stdout para comunicarse con el host.
allowed_origins
Lista de extensiones que deberían tener acceso al host de mensajería nativa. Los valores allowed-origins no pueden contener comodines.

Ubicación del host de mensajería nativa

La ubicación del archivo de manifiesto depende de la plataforma.

En Windows, el archivo de manifiesto se puede encontrar en cualquier parte del sistema de archivos. El instalador de aplicaciones debe crear una clave de registro, ya sea HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application o HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application, y establecer el valor predeterminado de esa clave en la ruta de acceso completa al archivo de manifiesto. Por ejemplo, usa el siguiente comando:

REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f

o con el siguiente archivo .reg:

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application]
@="C:\\path\\to\\nmh-manifest.json"

Cuando Chrome busca hosts de mensajería nativa, primero se consulta el registro de 32 bits y, luego, el de 64 bits.

En macOS y Linux, la ubicación del archivo de manifiesto del host de mensajería nativa varía según el navegador (Google Chrome o Chromium). Los hosts de mensajería nativa de todo el sistema se buscan en una ubicación fija, mientras que los hosts de mensajería nativa de nivel de usuario se buscan en el subdirectorio NativeMessagingHosts/ del directorio del perfil del usuario.

macOS (en todo el sistema)
Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: /Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
macOS (específica del usuario, ruta de acceso predeterminada)
Google Chrome: ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: ~/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
Linux (en todo el sistema)
Google Chrome: /etc/opt/chrome/native-messaging-hosts/com.my_company.my_application.json
Chromium: /etc/chromium/native-messaging-hosts/com.my_company.my_application.json
Linux (específica del usuario, ruta de acceso predeterminada)
Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

Protocolo de mensajería nativa

Chrome inicia cada host de mensajería nativa en un proceso separado y se comunica con él mediante la entrada estándar (stdin) y la salida estándar (stdout). Se usa el mismo formato para enviar mensajes en ambas direcciones; cada mensaje se serializa con JSON, codificado en UTF-8 y se antecede con una longitud de mensaje de 32 bits en orden de bytes nativo. El tamaño máximo de un solo mensaje del host de mensajería nativa es de 1 MB, principalmente para proteger a Chrome de aplicaciones nativas que funcionan mal. El tamaño máximo del mensaje enviado al host de mensajería nativa es de 4 GB.

El primer argumento para el host de mensajería nativa es el origen del llamador, que suele ser chrome-extension://[ID of allowed extension]. Esto permite que los hosts de mensajería nativa identifiquen la fuente del mensaje cuando se especifican varias extensiones en la clave allowed_origins del manifiesto de host de mensajería nativa.

En Windows, el host de mensajería nativa también recibe un argumento de línea de comandos con un controlador para la ventana nativa de Chrome que realiza la llamada: --parent-window=<decimal handle value>. Esto permite que el host de mensajería nativa cree ventanas nativas de IU que tengan el superior correcto. Ten en cuenta que este valor será 0 si el contexto de llamada es un service worker.

Cuando se crea un puerto de mensajería con runtime.connectNative(), Chrome inicia el proceso de host de mensajería nativa y la mantiene en ejecución hasta que se destruye el puerto. Por otro lado, cuando se envía un mensaje con runtime.sendNativeMessage() sin crear un puerto de mensajería, Chrome inicia un nuevo proceso de host de mensajería nativa para cada mensaje. En ese caso, el primer mensaje generado por el proceso del host se maneja como respuesta a la solicitud original, y Chrome lo pasará a la devolución de llamada de respuesta especificada cuando se llama a runtime.sendNativeMessage(). En ese caso, se ignoran todos los demás mensajes generados por el host de mensajería nativa.

Cómo conectarse a una aplicación nativa

El envío y la recepción de mensajes hacia y desde una aplicación nativa es muy similar a los mensajes entre extensiones. La diferencia principal es que se usa runtime.connectNative() en lugar de runtime.connect(), y runtime.sendNativeMessage() en lugar de runtime.sendMessage().

Para usar estos métodos, se debe declarar el permiso “nativeMessaging” en el archivo de manifiesto de tus extensiones.

Estos métodos no están disponibles en las secuencias de comandos de contenido, solo dentro de las páginas de tu extensión y el service worker. Si deseas comunicarte desde una secuencia de comandos de contenido a la aplicación nativa, envía el mensaje al service worker para pasarlo a la aplicación nativa.

En el siguiente ejemplo, se crea un objeto runtime.Port que está conectado al host de mensajería nativa com.my_company.my_application, comienza a escuchar mensajes de ese puerto y envía un mensaje saliente:

var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function (msg) {
  console.log('Received' + msg);
});
port.onDisconnect.addListener(function () {
  console.log('Disconnected');
});
port.postMessage({text: 'Hello, my_application'});

Usa runtime.sendNativeMessage para enviar un mensaje a la aplicación nativa sin crear un puerto, p.ej.:

chrome.runtime.sendNativeMessage(
  'com.my_company.my_application',
  {text: 'Hello'},
  function (response) {
    console.log('Received ' + response);
  }
);

Cómo depurar mensajes nativos

Cuando se producen ciertos errores de mensajería nativa, los resultados se escriben en el registro de errores de Chrome. Esto incluye los casos en que no se inicia el host de mensajería nativa, se escribe en stderr o se infringe el protocolo de comunicación. En Linux y macOS, se puede acceder a este registro iniciando Chrome desde la línea de comandos y observando su resultado en la terminal. En Windows, usa --enable-logging como se explica en Cómo habilitar el registro.

Estos son algunos errores comunes y sugerencias para solucionarlos:

No se pudo iniciar el host de mensajería nativa.

Verifica si tienes permisos suficientes para ejecutar el archivo de host de mensajería nativa.

El nombre de host de la mensajería nativa especificado no es válido.

Verifica si el nombre contiene caracteres no válidos. Solo se permiten caracteres alfanuméricos en minúscula, guiones bajos y puntos. Un nombre no puede comenzar ni terminar con un punto, y un punto no puede estar seguido de otro punto.

Se salió del host nativo.

La canalización hacia el host de mensajería nativa se rompía antes de que Chrome leyera el mensaje. Es probable que esto se inicie desde el host de mensajería nativa.

No se encontró el host de mensajería nativa especificado.

Verifica lo siguiente:

  • ¿El nombre está escrito correctamente en la extensión y en el archivo de manifiesto?
  • ¿El manifiesto se encuentra en el directorio correcto y con el nombre correcto? Consulta la ubicación del host de mensajería nativa para conocer los formatos esperados.
  • ¿El archivo de manifiesto tiene el formato correcto? En particular, ¿el JSON es válido y está bien formado? ¿Los valores coinciden con la definición de un manifiesto de host de mensajería nativa?
  • ¿Existe el archivo especificado en path? En Windows, las rutas de acceso pueden ser relativas, pero en macOS y Linux, las rutas deben ser absolutas.

El nombre de host del host de mensajería nativa no está registrado. (solo en Windows)

No se encontró el host de mensajería nativa en el registro de Windows. Vuelve a verificar con regedit si la clave realmente se creó y si coincide con el formato requerido, como se documenta en la ubicación del host de mensajería nativa.

Se prohíbe el acceso al host de mensajería nativa especificado.

¿El origen de la extensión aparece en allowed_origins?

Se produjo un error durante la comunicación con el host de mensajería nativa.

Esto indica una implementación incorrecta del protocolo de comunicación en el host de mensajería nativo.

  • Asegúrate de que todos los resultados de stdout cumplan con el protocolo de mensajería nativa. Si deseas imprimir algunos datos con fines de depuración, escribe en stderr.
  • Asegúrate de que la longitud del mensaje de 32 bits esté en el formato de número entero nativo de la plataforma (little-endian/big-endian).
  • La longitud del mensaje no debe superar los 1,024*1,024.
  • El tamaño del mensaje debe ser igual a la cantidad de bytes del mensaje. Esto puede diferir de la "longitud" de una string, ya que los caracteres pueden estar representados por varios bytes.
  • Solo para Windows: Asegúrate de que el modo de E/S del programa esté configurado en O_BINARY. De forma predeterminada, el modo de E/S es O_TEXT, que daña el formato del mensaje, ya que los saltos de línea (\n = 0A) se reemplazan por finales de línea de estilo Windows (\r\n = 0D 0A). El modo de E/S se puede establecer con __setmode.