Собственный обмен сообщениями

Расширения и приложения могут обмениваться сообщениями с собственными приложениями, используя API, аналогичный другим API передачи сообщений . Собственные приложения, поддерживающие эту функцию, должны зарегистрировать собственный узел обмена сообщениями , который знает, как взаимодействовать с расширением. Chrome запускает хост в отдельном процессе и взаимодействует с ним, используя потоки стандартного ввода и стандартного вывода.

Собственный хост обмена сообщениями

Чтобы зарегистрировать собственный хост обмена сообщениями, приложение должно установить файл манифеста, который определяет конфигурацию собственного хоста обмена сообщениями. Ниже приведен пример файла манифеста:

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

Файл манифеста узла собственной системы обмена сообщениями должен иметь действительный формат JSON и содержать следующие поля:

Имя Описание
name Имя собственного узла обмена сообщениями. Клиенты передают эту строку в runtime.connectNative или runtime.sendNativeMessage . Это имя может содержать только строчные буквы, цифры, символы подчеркивания и точки. Имя не может начинаться или заканчиваться точкой, а за точкой не может следовать другая точка.
description Краткое описание приложения.
path Путь к двоичному файлу узла обмена сообщениями. В Linux и OSX путь должен быть абсолютным. В Windows это может быть относительно каталога, в котором находится файл манифеста. Хост-процесс запускается с текущим каталогом, установленным в каталог, содержащий двоичный файл хоста. Например, если для этого параметра установлено значение C:\Application\nm_host.exe он будет запущен с текущего каталога C:\Application\ .
type Тип интерфейса, используемого для связи с собственным узлом обмена сообщениями. В настоящее время существует только одно возможное значение для этого параметра: stdio . Это указывает на то, что Chrome должен использовать stdin и stdout для связи с хостом.
allowed_origins Список расширений, которые должны иметь доступ к собственному узлу обмена сообщениями. Подстановочные знаки, такие как chrome-extension://*/* не допускаются.

Местоположение собственного узла обмена сообщениями

Расположение файла манифеста зависит от платформы.

В Windows файл манифеста может находиться в любом месте файловой системы. Установщик приложения должен создать ключ реестра HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ или HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ и установить значение по умолчанию для этого ключа, равное полному пути. в файл манифеста. Например, используя следующую команду:

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

или используя следующий .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"

Когда Chrome ищет собственные хосты обмена сообщениями, сначала запрашивается 32-битный реестр, а затем 64-битный реестр.

В OS X и Linux расположение файла манифеста собственного узла обмена сообщениями зависит от браузера (Google Chrome или Chromium). Собственные узлы обмена сообщениями на уровне всей системы просматриваются в фиксированном местоположении, тогда как собственные узлы обмена сообщениями на уровне пользователя просматриваются в подкаталоге в каталоге профиля пользователя, который называется NativeMessagingHosts .

  • OS X (общесистемная)
    • 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 (зависит от пользователя, путь по умолчанию )
    • 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 (общесистемный)
    • Google Chrome: /etc/opt/chrome/native-messaging-hosts/_com.my_company.my_application_.json
    • Хром: /etc/chromium/native-messaging-hosts/_com.my_company.my_application_.json
  • Linux (зависит от пользователя, путь по умолчанию )
    • Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Хром: ~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

Собственный протокол обмена сообщениями

Chrome запускает каждый собственный хост обмена сообщениями в отдельном процессе и взаимодействует с ним, используя стандартный ввод ( stdin ) и стандартный вывод ( stdout ). Для отправки сообщений в обоих направлениях используется один и тот же формат: каждое сообщение сериализуется с использованием JSON в кодировке UTF-8, и ему предшествует 32-битная длина сообщения в собственном порядке байтов. Максимальный размер одного сообщения от собственного узла обмена сообщениями составляет 1 МБ, главным образом для защиты Chrome от некорректного поведения собственных приложений. Максимальный размер сообщения, отправляемого на собственный узел обмена сообщениями, составляет 4 ГБ.

Первым аргументом собственного хоста обмена сообщениями является источник вызывающего абонента, обычно chrome-extension://[ID of allowed extension] . Это позволяет собственным узлам обмена сообщениями идентифицировать источник сообщения, если в ключе allowed_origins в манифесте собственного узла обмена сообщениями указано несколько расширений. Предупреждение . В Windows, в Chrome 54 и более ранних версиях, начало координат передавалось в качестве второго параметра вместо первого.

Когда порт обмена сообщениями создается с помощью runtime.connectNative , Chrome запускает собственный хост-процесс обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage без создания порта обмена сообщениями, Chrome запускает новый собственный хост-процесс обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное хост-процессом, обрабатывается как ответ на исходный запрос, т. е. Chrome передает его обратному вызову ответа, указанному при вызове runtime.sendNativeMessage . Все остальные сообщения, генерируемые собственным узлом обмена сообщениями, в этом случае игнорируются.

В Windows собственному хосту обмена сообщениями также передается аргумент командной строки с дескриптором вызывающего собственного окна Chrome: --parent-window=<decimal handle value> . Это позволяет собственному узлу обмена сообщениями создавать собственные окна пользовательского интерфейса, которые правильно являются родительскими. Обратите внимание, что это значение будет равно 0, если контекстом вызова является страница фонового сценария.

Подключение к родному приложению

Отправка и получение сообщений в собственное приложение и из него очень похоже на обмен сообщениями между расширениями. Основное отличие состоит в том, что вместо runtime.connect используется runtime.connectNative , а вместо runtime.sendMessageruntime.sendNativeMessage . Эти методы можно использовать только в том случае, если разрешение «nativeMessaging» объявлено в файле манифеста вашего приложения.

В следующем примере создается объект runtime.Port , который подключен к собственному узлу обмена сообщениями com.my_company.my_application , начинает прослушивать сообщения от этого порта и отправляет одно исходящее сообщение:

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 можно использовать для отправки сообщения в собственное приложение без создания порта, например:

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

Отладка встроенного обмена сообщениями

Когда собственный хост обмена сообщениями не запускается, записывает в stderr или нарушает протокол связи, выходные данные записываются в журнал ошибок Chrome. В Linux и OS X к этому журналу можно легко получить доступ, запустив Chrome из командной строки и просмотрев его вывод в терминале. В Windows используйте --enable-logging , как описано в разделе «Как включить ведение журнала» .

Вот некоторые ошибки и советы по решению проблем:

  • Не удалось запустить собственный хост обмена сообщениями.
    • Проверьте, есть ли у вас достаточные разрешения для выполнения файла.
  • Указано неверное имя хоста собственной системы обмена сообщениями.
    • Проверьте, содержит ли имя недопустимые символы. Допускаются только строчные буквы, цифры, символы подчеркивания и точки. Имя не может начинаться или заканчиваться точкой, а за точкой не может следовать другая точка.
  • Родной хост вышел.
    • Канал к собственному хосту обмена сообщениями был сломан до того, как сообщение было прочитано Chrome. Скорее всего, это инициируется вашим собственным хостом обмена сообщениями.
  • Указанный собственный хост обмена сообщениями не найден.
  • Имя хоста собственного узла обмена сообщениями не зарегистрировано. (только для Windows)
  • Доступ к указанному собственному хосту обмена сообщениями запрещен.
    • Указано ли происхождение расширения в allowed_origins ?
  • Ошибка при обмене данными с собственным хостом обмена сообщениями.
    • Это очень распространенная ошибка, указывающая на неправильную реализацию протокола связи на собственном узле обмена сообщениями.
    • Убедитесь, что весь вывод в stdout соответствует собственному протоколу обмена сообщениями . Если вы хотите распечатать некоторые данные для целей отладки, напишите в stderr .
    • Убедитесь, что длина 32-битного сообщения соответствует собственному целочисленному формату платформы (little-endian/big-endian).
    • Длина сообщения не должна превышать 1024*1024.
    • Размер сообщения должен быть равен количеству байтов в сообщении. Это может отличаться от «длины» строки, поскольку символы могут быть представлены несколькими байтами.
    • Только для Windows: убедитесь, что режим ввода-вывода программы установлен на O_BINARY . По умолчанию режим ввода-вывода — O_TEXT , который искажает формат сообщения, поскольку разрывы строк ( \n = 0A ) заменяются окончаниями строк в стиле Windows ( \r\n = 0D 0A ). Режим ввода-вывода можно установить с помощью __setmode .
,

Расширения и приложения могут обмениваться сообщениями с собственными приложениями, используя API, аналогичный другим API передачи сообщений . Собственные приложения, поддерживающие эту функцию, должны зарегистрировать собственный узел обмена сообщениями , который знает, как взаимодействовать с расширением. Chrome запускает хост в отдельном процессе и взаимодействует с ним, используя потоки стандартного ввода и стандартного вывода.

Собственный хост обмена сообщениями

Чтобы зарегистрировать собственный хост обмена сообщениями, приложение должно установить файл манифеста, который определяет конфигурацию собственного хоста обмена сообщениями. Ниже приведен пример файла манифеста:

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

Файл манифеста узла собственной системы обмена сообщениями должен иметь действительный формат JSON и содержать следующие поля:

Имя Описание
name Имя собственного узла обмена сообщениями. Клиенты передают эту строку в runtime.connectNative или runtime.sendNativeMessage . Это имя может содержать только строчные буквы, цифры, символы подчеркивания и точки. Имя не может начинаться или заканчиваться точкой, а за точкой не может следовать другая точка.
description Краткое описание приложения.
path Путь к двоичному файлу узла обмена сообщениями. В Linux и OSX путь должен быть абсолютным. В Windows это может быть относительно каталога, в котором находится файл манифеста. Хост-процесс запускается с текущим каталогом, установленным в каталог, содержащий двоичный файл хоста. Например, если для этого параметра установлено значение C:\Application\nm_host.exe он будет запущен с текущего каталога C:\Application\ .
type Тип интерфейса, используемого для связи с собственным узлом обмена сообщениями. В настоящее время существует только одно возможное значение для этого параметра: stdio . Это указывает на то, что Chrome должен использовать stdin и stdout для связи с хостом.
allowed_origins Список расширений, которые должны иметь доступ к собственному узлу обмена сообщениями. Подстановочные знаки, такие как chrome-extension://*/* не допускаются.

Местоположение собственного узла обмена сообщениями

Расположение файла манифеста зависит от платформы.

В Windows файл манифеста может находиться в любом месте файловой системы. Установщик приложения должен создать ключ реестра HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ или HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ и установить значение по умолчанию для этого ключа, равное полному пути. в файл манифеста. Например, используя следующую команду:

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

или используя следующий .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"

Когда Chrome ищет собственные хосты обмена сообщениями, сначала запрашивается 32-битный реестр, а затем 64-битный реестр.

В OS X и Linux расположение файла манифеста собственного узла обмена сообщениями зависит от браузера (Google Chrome или Chromium). Собственные узлы обмена сообщениями на уровне всей системы просматриваются в фиксированном местоположении, тогда как собственные узлы обмена сообщениями на уровне пользователя просматриваются в подкаталоге в каталоге профиля пользователя, который называется NativeMessagingHosts .

  • OS X (общесистемная)
    • 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 (зависит от пользователя, путь по умолчанию )
    • 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 (общесистемный)
    • Google Chrome: /etc/opt/chrome/native-messaging-hosts/_com.my_company.my_application_.json
    • Хром: /etc/chromium/native-messaging-hosts/_com.my_company.my_application_.json
  • Linux (зависит от пользователя, путь по умолчанию )
    • Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Хром: ~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

Собственный протокол обмена сообщениями

Chrome запускает каждый собственный хост обмена сообщениями в отдельном процессе и взаимодействует с ним, используя стандартный ввод ( stdin ) и стандартный вывод ( stdout ). Для отправки сообщений в обоих направлениях используется один и тот же формат: каждое сообщение сериализуется с использованием JSON в кодировке UTF-8, и ему предшествует 32-битная длина сообщения в собственном порядке байтов. Максимальный размер одного сообщения от собственного узла обмена сообщениями составляет 1 МБ, главным образом для защиты Chrome от некорректного поведения собственных приложений. Максимальный размер сообщения, отправляемого на собственный узел обмена сообщениями, составляет 4 ГБ.

Первым аргументом собственного хоста обмена сообщениями является источник вызывающего абонента, обычно chrome-extension://[ID of allowed extension] . Это позволяет собственным узлам обмена сообщениями идентифицировать источник сообщения, если в ключе allowed_origins в манифесте собственного узла обмена сообщениями указано несколько расширений. Предупреждение . В Windows, в Chrome 54 и более ранних версиях, начало координат передавалось в качестве второго параметра вместо первого.

Когда порт обмена сообщениями создается с помощью runtime.connectNative , Chrome запускает собственный хост-процесс обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage без создания порта обмена сообщениями, Chrome запускает новый собственный хост-процесс обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное хост-процессом, обрабатывается как ответ на исходный запрос, т. е. Chrome передает его обратному вызову ответа, указанному при вызове runtime.sendNativeMessage . Все остальные сообщения, генерируемые собственным узлом обмена сообщениями, в этом случае игнорируются.

В Windows собственному хосту обмена сообщениями также передается аргумент командной строки с дескриптором вызывающего собственного окна Chrome: --parent-window=<decimal handle value> . Это позволяет собственному узлу обмена сообщениями создавать собственные окна пользовательского интерфейса, которые правильно являются родительскими. Обратите внимание, что это значение будет равно 0, если контекстом вызова является страница фонового сценария.

Подключение к родному приложению

Отправка и получение сообщений в собственное приложение и из него очень похоже на обмен сообщениями между расширениями. Основное отличие состоит в том, что вместо runtime.connect используется runtime.connectNative , а вместо runtime.sendMessageruntime.sendNativeMessage . Эти методы можно использовать только в том случае, если разрешение «nativeMessaging» объявлено в файле манифеста вашего приложения.

В следующем примере создается объект runtime.Port , который подключен к собственному узлу обмена сообщениями com.my_company.my_application , начинает прослушивать сообщения от этого порта и отправляет одно исходящее сообщение:

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 можно использовать для отправки сообщения в собственное приложение без создания порта, например:

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

Отладка встроенного обмена сообщениями

Когда собственный хост обмена сообщениями не запускается, записывает в stderr или нарушает протокол связи, выходные данные записываются в журнал ошибок Chrome. В Linux и OS X к этому журналу можно легко получить доступ, запустив Chrome из командной строки и просмотрев его вывод в терминале. В Windows используйте --enable-logging , как описано в разделе «Как включить ведение журнала» .

Вот некоторые ошибки и советы по решению проблем:

  • Не удалось запустить собственный хост обмена сообщениями.
    • Проверьте, есть ли у вас достаточные разрешения для выполнения файла.
  • Указано неверное имя хоста собственной системы обмена сообщениями.
    • Проверьте, содержит ли имя недопустимые символы. Допускаются только строчные буквы, цифры, символы подчеркивания и точки. Имя не может начинаться или заканчиваться точкой, а за точкой не может следовать другая точка.
  • Родной хост вышел.
    • Канал к собственному хосту обмена сообщениями был сломан до того, как сообщение было прочитано Chrome. Скорее всего, это инициируется вашим собственным хостом обмена сообщениями.
  • Указанный собственный хост обмена сообщениями не найден.
  • Имя хоста собственного узла обмена сообщениями не зарегистрировано. (только для Windows)
  • Доступ к указанному собственному хосту обмена сообщениями запрещен.
    • Указано ли происхождение расширения в allowed_origins ?
  • Ошибка при обмене данными с собственным хостом обмена сообщениями.
    • Это очень распространенная ошибка, указывающая на неправильную реализацию протокола связи на собственном узле обмена сообщениями.
    • Убедитесь, что весь вывод в stdout соответствует собственному протоколу обмена сообщениями . Если вы хотите распечатать некоторые данные для целей отладки, напишите в stderr .
    • Убедитесь, что длина 32-битного сообщения соответствует собственному целочисленному формату платформы (little-endian/big-endian).
    • Длина сообщения не должна превышать 1024*1024.
    • Размер сообщения должен быть равен количеству байтов в сообщении. Это может отличаться от «длины» строки, поскольку символы могут быть представлены несколькими байтами.
    • Только для Windows: убедитесь, что режим ввода-вывода программы установлен на O_BINARY . По умолчанию режим ввода-вывода — O_TEXT , который искажает формат сообщения, поскольку разрывы строк ( \n = 0A ) заменяются окончаниями строк в стиле Windows ( \r\n = 0D 0A ). Режим ввода-вывода можно установить с помощью __setmode .