Mensagens nativas

As extensões podem trocar mensagens com aplicativos nativos usando uma API semelhante às outras APIs de transmissão de mensagens. Os aplicativos nativos com suporte a esse recurso precisam registrar um host de mensagens nativo que possa se comunicar com a extensão. O Chrome inicia o host em um processo separado e se comunica com ele usando streams de entrada e saída padrão.

Host de mensagens nativas

Para registrar um host de mensagens nativas, o app precisa salvar um arquivo que defina a configuração do host de mensagens nativas.

Este é um exemplo do arquivo:

{
  "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/"]
}

O arquivo de manifesto do host de mensagens nativas precisa ser um JSON válido e conter os seguintes campos:

name
Nome do host de mensagens nativas. Os clientes transmitem essa string para runtime.connectNative() ou runtime.sendNativeMessage(). Esse nome só pode conter caracteres alfanuméricos minúsculos, sublinhados e pontos. O nome não pode começar ou terminar com um ponto, e um ponto não pode ser seguido por outro ponto.
description
Breve descrição do aplicativo.
path
Caminho para o binário do host de mensagens nativas. No Linux e no macOS, o caminho precisa ser absoluto. No Windows, ele pode ser relativo ao diretório que contém o arquivo de manifesto. O processo do host é iniciado com o diretório atual definido como o diretório que contém o binário do host. Por exemplo, se o parâmetro for definido como C:\Application\nm_host.exe, ele será iniciado com o diretório atual "C:\Application".
type
Tipo da interface usada para se comunicar com o host de mensagens nativas. Esse parâmetro tem um valor possível: stdio. Ele indica que o Chrome precisa usar stdin e stdout para se comunicar com o host.
allowed_origins
Lista de extensões que precisam ter acesso ao host de mensagens nativas. Os valores allowed-origins não podem conter caracteres curinga.

Local do host de mensagens nativas

O local do arquivo de manifesto depende da plataforma.

No Windows, o arquivo de manifesto pode estar localizado em qualquer lugar no sistema de arquivos. O instalador do aplicativo precisa criar uma chave de registro, HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application ou HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application, e definir o valor padrão dessa chave como o caminho completo para o arquivo de manifesto. Por exemplo, use o seguinte 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

ou usando o seguinte arquivo .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"

Quando o Chrome procura hosts de mensagens nativas, primeiro o registro de 32 bits é consultado, depois o de 64 bits.

No macOS e no Linux, o local do arquivo de manifesto do host de mensagens nativas varia de acordo com o navegador (Google Chrome ou Chromium). Os hosts de mensagens nativas do sistema são pesquisados em um local fixo, enquanto os hosts de mensagens nativas no nível do usuário são pesquisados no subdiretório NativeMessagingHosts/ do diretório do perfil do usuário.

macOS (todo o 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 (caminho padrão específico do usuário)
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 (todo o 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 (caminho padrão específico do usuário)
Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json
Chromium: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

Protocolo de mensagens nativas

O Chrome inicia cada host de mensagens nativas em um processo separado e se comunica com ele usando a entrada padrão (stdin) e a saída padrão (stdout). O mesmo formato é usado para enviar mensagens em ambas as direções. Cada mensagem é serializada usando JSON, codificada em UTF-8 e precedida por um tamanho de mensagem de 32 bits na ordem de bytes nativos. O tamanho máximo de uma única mensagem do host de mensagens nativas é de 1 MB, principalmente para proteger o Chrome contra aplicativos nativos que apresentam comportamento inadequado. O tamanho máximo da mensagem enviada ao host de mensagens nativas é de 4 GB.

O primeiro argumento para o host de mensagens nativas é a origem do autor da chamada, geralmente chrome-extension://[ID of allowed extension]. Isso permite que os hosts de mensagens nativas identifiquem a origem da mensagem quando várias extensões são especificadas na chave allowed_origins no manifesto do host de mensagens nativas.

No Windows, o host de mensagens nativas também recebe um argumento de linha de comando com um identificador para a janela nativa do Chrome que chama: --parent-window=<decimal handle value>. Isso permite que o host de mensagens nativas crie janelas de IU nativas com o pai correto. Observe que esse valor será 0 se o contexto de chamada for um service worker.

Quando uma porta de mensagens é criada usando runtime.connectNative(), o Chrome inicia o processo do host de mensagens nativas e o mantém em execução até que a porta seja destruída. Por outro lado, quando uma mensagem é enviada usando runtime.sendNativeMessage(), sem criar uma porta de mensagens, o Chrome inicia um novo processo de host de mensagens nativas para cada mensagem. Nesse caso, a primeira mensagem gerada pelo processo do host é processada como uma resposta à solicitação original, e o Chrome a transmite para o callback de resposta especificado quando runtime.sendNativeMessage() é chamado. Nesse caso, todas as outras mensagens geradas pelo host de mensagens nativas serão ignoradas.

Como se conectar a um aplicativo nativo

O envio e o recebimento de mensagens de e para um app nativo é muito semelhante às mensagens entre extensões. A principal diferença é que runtime.connectNative() é usado em vez de runtime.connect() e runtime.sendNativeMessage() é usado em vez de runtime.sendMessage().

Para usar esses métodos, a permissão "nativeMessaging" precisa ser declarada no arquivo de manifesto das extensões.

Esses métodos não estão disponíveis nos scripts de conteúdo, apenas nas páginas e no service worker da extensão. Se você quiser se comunicar de um script de conteúdo com o aplicativo nativo, envie a mensagem para o service worker para transmiti-la ao aplicativo nativo.

O exemplo a seguir cria um objeto runtime.Port conectado ao host de mensagens nativas com.my_company.my_application, começa a detectar mensagens dessa porta e envia uma mensagem de saída:

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'});

Use runtime.sendNativeMessage para enviar uma mensagem ao aplicativo nativo sem criar uma porta. Por exemplo:

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

Depurar mensagens nativas

Quando ocorrem determinadas falhas de mensagens nativas, a saída é gravada no registro de erros do Chrome. Isso inclui quando o host de mensagens nativas falha ao iniciar, grava em stderr ou viola o protocolo de comunicação. Para acessar esse registro no Linux e no macOS, basta iniciar o Chrome na linha de comando e observar a saída no terminal. No Windows, use --enable-logging, conforme explicado em Como ativar a geração de registros.

Confira alguns erros comuns e dicas para resolvê-los:

Falha ao iniciar o host de mensagens nativas.

Verifique se você tem permissões suficientes para executar o arquivo host de mensagens nativas.

O nome de host de mensagens nativas especificado é inválido.

Verifique se o nome contém caracteres inválidos. Apenas caracteres alfanuméricos minúsculos, sublinhados e pontos são permitidos. Um nome não pode começar ou terminar com um ponto, e um ponto não pode ser seguido por outro ponto.

O host nativo saiu.

O canal para o host de mensagens nativas estava corrompido antes de a mensagem ser lida pelo Chrome. Isso provavelmente é iniciado no host de mensagens nativas.

O host de mensagens nativas especificado não foi encontrado.

Verifique os seguintes itens:

  • O nome está escrito corretamente na extensão e no arquivo de manifesto?
  • O manifesto está no diretório certo e com o nome certo? Consulte o local do host de mensagens nativas para saber os formatos esperados.
  • O arquivo de manifesto está no formato correto? Especificamente, o JSON é válido e bem formado? Os valores correspondem à definição de um manifesto de host de mensagens nativas?
  • O arquivo especificado em path existe? No Windows, os caminhos podem ser relativos, mas no macOS e no Linux, os caminhos precisam ser absolutos.

O nome do host do host de mensagens nativas não está registrado. (somente para Windows)

O host de mensagens nativas não foi encontrado no registro do Windows. Verifique usando regedit se a chave realmente foi criada e corresponde ao formato necessário, conforme documentado no local do host das mensagens nativas.

O acesso ao host de mensagens nativas especificado é proibido.

A origem da extensão está listada em allowed_origins?

Ocorreu um erro ao se comunicar com o host de mensagens nativas.

Isso indica uma implementação incorreta do protocolo de comunicação no host de mensagens nativas.

  • Confira se toda a saída no stdout segue o protocolo de mensagens nativas. Caso queira exibir alguns dados para fins de depuração, grave em stderr.
  • Verifique se o tamanho da mensagem de 32 bits está no formato inteiro nativo da plataforma (little-endian / big-endian).
  • O tamanho da mensagem não pode exceder 1.024 x 1.024.
  • O tamanho da mensagem precisa ser igual ao número de bytes dela. Isso pode ser diferente do "comprimento" de uma string, porque os caracteres podem ser representados por vários bytes.
  • Somente Windows:confira se o modo de E/S do programa está definido como O_BINARY. Por padrão, o modo de E/S é O_TEXT, o que corrompe o formato da mensagem porque as quebras de linha (\n = 0A) são substituídas por finalidades de linha no estilo do Windows (\r\n = 0D 0A). O modo de E/S pode ser definido usando __setmode.