Las extensiones pueden intercambiar mensajes con aplicaciones nativas a través de una API similar a las otras APIs de transferencia 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 independiente y se comunica con él a través de flujos de entrada y salida estándares.
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 ser un JSON válido y contener los siguientes campos:
name- Nombre del host de mensajería nativa. Los clientes pasan esta cadena a
runtime.connectNative()oruntime.sendNativeMessage(). Este nombre solo puede contener caracteres alfanuméricos en minúscula, guiones bajos y puntos. El nombre no puede comenzar ni terminar con un punto, y no puede haber dos puntos seguidos. description- Descripción breve de la aplicación.
path- Ruta de acceso al objeto binario del host de mensajería nativa. En Linux y macOS, la ruta debe ser absoluta. En Windows, puede ser relativa al directorio que contiene el archivo de manifiesto. El proceso del host se inicia con el directorio actual establecido 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 usarstdinystdoutpara comunicarse con el host. allowed_origins- Lista de extensiones que deberían tener acceso al host de mensajería nativa. Los valores de
allowed_originsno 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 ubicar en cualquier parte del sistema de archivos. El instalador de la aplicación 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, con 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, Chrome for Testing 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 a nivel del usuario se buscan en el subdirectorio NativeMessagingHosts/ del directorio de perfil del usuario.
- macOS (en todo el sistema)
- Google Chrome:
/Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome for Testing:
/Library/Google/ChromeForTesting/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json - macOS (ruta de acceso predeterminada específica del usuario)
- Google Chrome:
~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome for Testing:
~/Library/Application Support/Google/ChromeForTesting/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 - Google Chrome for Testing:
/etc/opt/chrome_for_testing/native-messaging-hosts/com.my_company.my_application.json - Chromium:
/etc/chromium/native-messaging-hosts/com.my_company.my_application.json - Linux (ruta de acceso específica del usuario, predeterminada)
- Google Chrome:
~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome for Testing:
~/.config/google-chrome-for-testing/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 a través de 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, se codifica en UTF-8 y está precedido por 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 Chrome de aplicaciones nativas con un comportamiento inadecuado. El tamaño máximo del mensaje que se envía al host de mensajería nativa es de 64 MiB.
El primer argumento para el host de mensajería nativa es el origen de la entidad que llama, 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 del host de mensajería nativa.
En Windows, también se pasa al host de mensajería nativa un argumento de línea de comandos con un identificador 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 de IU nativas que estén correctamente vinculadas a un elemento superior. 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 un proceso host de mensajería nativa y lo 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 controla como una respuesta a la solicitud original, y Chrome lo pasará a la devolución de llamada de respuesta especificada cuando se llame a runtime.sendNativeMessage(). En ese caso, se ignoran todos los demás mensajes que genera 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 son muy similares a la mensajería entre extensiones. La principal diferencia es que se usa runtime.connectNative() en lugar de runtime.connect() y runtime.sendNativeMessage() en lugar de runtime.sendMessage().
Para usar estos métodos, el permiso "nativeMessaging" debe declararse en el archivo de manifiesto de la extensión.
Estos métodos no están disponibles dentro de los secuencias de comandos de contenido, solo dentro de las páginas y el service worker de tu extensión. Para comunicarte desde un script de contenido con la aplicación nativa, envía el mensaje a tu service worker para que lo pase a la aplicación nativa.
En el siguiente ejemplo, se crea un objeto runtime.Port conectado al host de mensajería nativa com.my_company.my_application, se comienza a escuchar los mensajes de ese puerto y se envía un mensaje saliente:
const port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener((msg) => {
console.log('Received', msg);
});
port.onDisconnect.addListener(() => {
if (chrome.runtime.lastError) {
console.error(
'Disconnected due to error:',
chrome.runtime.lastError.message
);
} else {
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'},
(response) => {
if (chrome.runtime.lastError) {
console.error(
'Error sending native message:',
chrome.runtime.lastError.message
);
return;
}
console.log('Received', response);
}
);
Cómo depurar la mensajería nativa
Cuando se producen errores de mensajería nativa, la salida de diagnóstico se escribe en el registro de errores de Chrome.
Linux y macOS
# Linux
google-chrome --enable-logging=stderr --log-level=1 2>&1 | \
grep -E "native_messag|launch_context"
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--enable-logging=stderr --log-level=1 2>&1 | \
grep -E "native_messag|launch_context"
Windows
Inicia Chrome con el registro habilitado:
chrome.exe --enable-logging --log-level=1
Pasa --user-data-dir="%TEMP%\nm-debug" para iniciar una instancia separada sin adjuntarla a un proceso de Chrome existente.
Para ver el resultado, transmite chrome_debug.log con PowerShell:
$log = "$env:LOCALAPPDATA\Google\Chrome\User Data\chrome_debug.log"
Get-Content -Wait $log | Select-String "native_messag|launch_context"
También puedes abrir chrome_debug.log en un editor de texto y buscar launch_context.cc o native_message_process_host.cc.
Detalles clave del registro
- Los errores de búsqueda y análisis del manifiesto en
launch_context.ccse registran como advertencias. Usa--log-level=1en lugar de2(ERROR), que suprime estos diagnósticos de inicio. - Busca
launch_contextpara encontrar errores de inicio de manifiesto y binarios, ynative_messagpara encontrar errores de comunicación de canalización y tamaño de carga útil.
Errores comunes
Estos son algunos errores comunes y sugerencias para solucionarlos:
No se pudo iniciar el host de mensajería nativa.
Comprueba si tienes permisos suficientes para ejecutar el archivo del host de mensajería nativa.
Se especificó un nombre de host de mensajería nativa no válido.
Comprueba 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 no puede haber dos puntos seguidos.
El host nativo salió.
La canalización hacia el host de mensajería nativa se interrumpió antes de que Chrome leyera el mensaje. Lo más probable es que se haya iniciado desde tu 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?
- En Windows, ¿la clave de registro existe en
HKEY_CURRENT_USERoHKEY_LOCAL_MACHINE, y su valor predeterminado apunta a la ruta de acceso completa del manifiesto? Chrome primero consulta la vista del registro de 32 bits y, luego, la de 64 bits. Usaregeditpara verificar la clave. Consulta la ubicación del host de mensajería nativa. - En macOS y Linux, ¿el archivo de manifiesto se encuentra en el directorio esperado y tiene el nombre del host (como
com.my_company.my_application.json)? Consulta la ubicación del host de mensajería nativa. - ¿El archivo de manifiesto tiene el formato correcto? En particular, ¿el JSON es válido y está bien formado, y 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 pueden ser relativas, pero en macOS y Linux, deben ser absolutas.
Se prohibió el acceso al host de mensajería nativa especificado.
¿El origen de la extensión aparece en allowed_origins?
Se produjo un error al comunicarse con el host de mensajería nativa.
Esto indica una implementación incorrecta del protocolo de comunicación en el host de mensajería nativa.
- Asegúrate de que todos los resultados en
stdoutcumplan con el protocolo de mensajería nativa. Si quieres imprimir algunos datos para depurar, escribe enstderr. - 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 exceder los 1,024*1,024.
- El tamaño del mensaje debe ser igual a la cantidad de bytes que contiene. Esto puede diferir de la "longitud" de una cadena, ya que los caracteres pueden representarse con varios bytes.
- Solo para Windows: Asegúrate de que el modo de E/S del programa esté configurado como
O_BINARY. De forma predeterminada, el modo de E/S esO_TEXT, lo 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 configurar con__setmode.