Messagerie native

Les extensions et les applications peuvent échanger des messages avec des applications natives à l'aide d'une API semblable aux autres API de transmission de messages. Les applications natives compatibles avec cette fonctionnalité doivent enregistrer un hôte de messagerie natif capable de communiquer avec l'extension. Chrome démarre l'hôte dans un processus distinct et communique avec lui à l'aide de flux d'entrée et de sortie standards.

Hôte de messagerie native

Pour enregistrer un hôte de messagerie natif, l'application doit installer un fichier manifeste qui définit la configuration de l'hôte de messagerie native. Voici un exemple de fichier manifeste:

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

Le fichier manifeste de l'hôte de messagerie native doit être au format JSON valide et contenir les champs suivants:

NomDescription
nameNom de l'hôte de messagerie native. Les clients transmettent cette chaîne à runtime.connectNative ou runtime.sendNativeMessage. Ce nom ne peut contenir que des caractères alphanumériques en minuscules, des traits de soulignement et des points. Le nom ne peut pas commencer ni se terminer par un point, et un point ne peut pas être suivi par un autre point.
descriptionBrève description de l'application.
pathChemin d'accès au binaire de l'hôte de messagerie native. Sous Linux et OSX, le chemin d'accès doit être absolu. Sous Windows, il peut s'agir du répertoire dans lequel se trouve le fichier manifeste. Le processus hôte démarre avec le répertoire actuel qui contient le binaire de l'hôte. Par exemple, si ce paramètre est défini sur C:\Application\nm_host.exe, il sera démarré avec le répertoire actuel C:\Application\.
typeType de l'interface utilisée pour communiquer avec l'hôte de messagerie native. Actuellement, il n'existe qu'une seule valeur possible pour ce paramètre: stdio. Il indique que Chrome doit utiliser stdin et stdout pour communiquer avec l'hôte.
allowed_originsListe des extensions qui doivent avoir accès à l'hôte de messagerie native. Les caractères génériques tels que chrome-extension://*/* ne sont pas autorisés.

Emplacement de l'hôte de messagerie native

L'emplacement du fichier manifeste dépend de la plate-forme.

Sous Windows, le fichier manifeste peut se trouver n'importe où dans le système de fichiers. Le programme d'installation de l'application doit créer la clé de registre 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_, et définir la valeur par défaut de cette clé sur le chemin d'accès complet au fichier manifeste. Par exemple, en utilisant la commande suivante:

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 à l'aide du fichier .reg suivant:

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

Lorsque Chrome recherche des hôtes de messagerie native, le registre 32 bits est d'abord interrogé, puis le registre 64 bits.

Sous OS X et Linux, l'emplacement du fichier manifeste de l'hôte de messagerie native varie en fonction du navigateur (Google Chrome ou Chromium). Les hôtes de messagerie natifs au niveau du système sont recherchés à un emplacement fixe, tandis que les hôtes de messagerie natifs au niveau de l'utilisateur sont recherchés dans un sous-répertoire du répertoire des profils utilisateur appelé NativeMessagingHosts.

  • OS X (à l'échelle du système)
    • Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: /Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
  • OS X (spécifique à l'utilisateur, chemin d'accès par défaut)
    • 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 (à l'échelle du système)
    • 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 (spécifique à l'utilisateur, chemin d'accès par défaut)
    • Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: ~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

Protocole de messagerie native

Chrome démarre chaque hôte de messagerie native dans un processus distinct et communique avec lui à l'aide d'une entrée standard (stdin) et d'une sortie standard (stdout). Le même format est utilisé pour envoyer des messages dans les deux sens: chaque message est sérialisé au format JSON encodé en UTF-8 et est précédé d'une longueur de message de 32 bits dans l'ordre des octets natifs. La taille maximale d'un message envoyé par l'hôte de messagerie native est de 1 Mo, principalement pour protéger Chrome contre le comportement défaillant des applications natives. La taille maximale du message envoyé à l'hôte de messagerie native est de 4 Go.

Le premier argument de l'hôte de messagerie native est l'origine de l'appelant, généralement chrome-extension://[ID of allowed extension]. Cela permet aux hôtes de messagerie native d'identifier la source du message lorsque plusieurs extensions sont spécifiées dans la clé allowed_origins du fichier manifeste de l'hôte de messagerie native. Avertissement: Sous Windows, à partir de Chrome 54, l'origine était transmise en tant que deuxième paramètre au lieu du premier.

Lorsqu'un port de messagerie est créé à l'aide de runtime.connectNative, Chrome lance le processus hôte de messagerie native et le poursuit jusqu'à ce que le port soit détruit. En revanche, lorsqu'un message est envoyé à l'aide de runtime.sendNativeMessage, sans créer de port de messagerie, Chrome lance un nouveau processus hôte de messagerie natif pour chaque message. Dans ce cas, le premier message généré par le processus hôte est géré en tant que réponse à la requête d'origine, c'est-à-dire que Chrome le transmet au rappel de réponse spécifié lors de l'appel de runtime.sendNativeMessage. Dans ce cas, tous les autres messages générés par l'hôte de messagerie native sont ignorés.

Sous Windows, l'hôte de messagerie native reçoit également un argument de ligne de commande avec un handle vers la fenêtre native Chrome appelante: --parent-window=<decimal handle value>. Cela permet à l'hôte de messagerie natif de créer des fenêtres d'interface utilisateur natives dont les parents sont correctement parents. Notez que cette valeur sera 0 si le contexte appelant est une page de script en arrière-plan.

Se connecter à une application native

L'envoi et la réception de messages depuis et vers une application native est très semblable à la messagerie multi-extension. La principale différence est que runtime.connectNative est utilisé à la place de runtime.connect, et runtime.sendNativeMessage à la place d'runtime.sendMessage. Ces méthodes ne peuvent être utilisées que si l'autorisation"nativeMessaging" est déclarée dans le fichier manifeste de votre application.

L'exemple suivant crée un objet runtime.Port connecté à l'hôte de messagerie native com.my_company.my_application, commence à écouter les messages de ce port et envoie un message sortant:

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

runtime.sendNativeMessage pour envoyer un message à une application native sans créer de port, par exemple :

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

Déboguer la messagerie native

Lorsque l'hôte de messagerie native ne démarre pas, écrit dans stderr ou ne respecte pas le protocole de communication, la sortie est écrite dans le journal d'erreurs de Chrome. Sous Linux et OS X, vous pouvez facilement accéder à ce journal en démarrant Chrome à partir de la ligne de commande et en observant sa sortie dans le terminal. Sous Windows, utilisez --enable-logging comme expliqué dans la section Activer la journalisation.

Voici quelques erreurs et conseils pour résoudre les problèmes:

  • Échec du démarrage de l'hôte de messagerie native.
    • Vérifiez si vous disposez des autorisations nécessaires pour exécuter le fichier.
  • Le nom d'hôte de messagerie natif spécifié n'est pas valide.
    • Vérifiez si le nom contient des caractères non valides. Seuls les caractères alphanumériques en minuscules, les traits de soulignement et les points sont autorisés. Un nom ne peut pas commencer ni se terminer par un point, et un point ne peut pas être suivi d'un autre point.
  • L'hôte natif s'est fermé.
    • Le tuyau menant à l'hôte de messagerie native était défaillant avant que le message ne soit lu par Chrome. Cette opération a probablement été lancée à partir de votre hôte de messagerie native.
  • L'hôte de messagerie native spécifié est introuvable.
    • Le nom est-il correctement orthographié dans l'extension et dans le fichier manifeste ?
    • Le fichier manifeste est-il placé dans le bon répertoire et porte-t-il le bon nom ? Consultez la section Emplacement de l'hôte de messagerie native pour connaître les formats attendus.
    • Le format du fichier manifeste est-il correct ? En particulier, la syntaxe JSON est-elle correcte et les valeurs correspondent-elles à la définition d'un fichier manifeste d'hôte de messagerie native ?
    • Le fichier spécifié dans path existe-t-il ? Sous Windows, les chemins d'accès peuvent être relatifs, mais sous OS X et Linux, ils doivent être absolus.
  • Le nom d'hôte de l'hôte de messagerie natif n'est pas enregistré. (Windows uniquement)
    • L'hôte de messagerie native est introuvable dans le registre Windows. À l'aide de regedit, vérifiez si la clé a bien été créée et qu'elle correspond au format requis, comme indiqué sur la page Emplacement hôte de la messagerie native.
  • L'accès à l'hôte de messagerie native spécifié est interdit.
    • L'origine de l'extension est-elle répertoriée dans allowed_origins ?
  • Erreur lors de la communication avec l'hôte de messagerie native.
    • Il s'agit d'une erreur très courante qui indique une mise en œuvre incorrecte du protocole de communication dans l'hôte de messagerie native.
    • Assurez-vous que toute la sortie dans stdout respecte le protocole de messagerie natif. Si vous souhaitez imprimer certaines données à des fins de débogage, écrivez dans stderr.
    • Assurez-vous que la longueur du message 32 bits est exprimée au format entier natif de la plate-forme (little-endian/big-endian).
    • La longueur du message ne doit pas dépasser 1 024*1 024.
    • La taille du message doit être égale au nombre d'octets qu'il contient. Cette valeur peut différer de la "longueur" d'une chaîne, car les caractères peuvent être représentés par plusieurs octets.
    • Windows uniquement: assurez-vous que le mode d'E/S du programme est défini sur O_BINARY. Par défaut, le mode d'E/S est O_TEXT, ce qui altère le format du message lorsque des sauts de ligne (\n = 0A) sont remplacés par des fin de ligne de style Windows (\r\n = 0D 0A). Le mode E/S peut être défini à l'aide de __setmode.