Расширения могут обмениваться сообщениями с нативными приложениями, используя 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 и macOS путь должен быть абсолютным. В Windows он может быть относительным к каталогу, содержащему файл манифеста. Процесс хоста запускается с текущим каталогом, установленным на каталог, содержащий исполняемый файл хоста. Например, если этот параметр установлен на
C:\Application\nm_host.exe, то он будет запущен с текущим каталогом `C:\Application`. -
type - Тип интерфейса, используемого для связи с собственным хостом обмена сообщениями. Этот параметр имеет одно возможное значение:
stdio. Он указывает, что Chrome должен использоватьstdinиstdoutдля связи с хостом. -
allowed_origins - Список расширений, которые должны иметь доступ к собственному хосту обмена сообщениями. Значения
allowed-originsне могут содержать подстановочные знаки.
Местоположение хоста нативного обмена сообщениями
Расположение файла манифеста зависит от платформы.
В 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-битный.
В macOS и Linux расположение файла манифеста нативного сервера обмена сообщениями различается в зависимости от браузера (Google Chrome, Google Chrome для тестирования или Chromium). Поиск нативных серверов обмена сообщениями в масштабе всей системы осуществляется в фиксированном месте, в то время как поиск нативных серверов обмена сообщениями на уровне пользователя осуществляется в подкаталоге NativeMessagingHosts/ каталога профиля пользователя .
- macOS (в масштабах всей системы)
- Google Chrome:
/Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
/Library/Google/ChromeForTesting/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json - macOS (путь по умолчанию , специфичный для пользователя)
- Google Chrome:
~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
~/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 (в масштабах всей системы)
- Google Chrome:
/etc/opt/chrome/native-messaging-hosts/com.my_company.my_application.json - Google Chrome для тестирования:
/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 (путь по умолчанию , специфичный для пользователя)
- Google Chrome:
~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
~/.config/google-chrome-for-testing/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json
Собственный протокол обмена сообщениями
Chrome запускает каждый собственный хост обмена сообщениями в отдельном процессе и взаимодействует с ним, используя стандартный ввод ( stdin ) и стандартный вывод ( stdout ). Для отправки сообщений в обоих направлениях используется один и тот же формат; каждое сообщение сериализуется в формате JSON, кодируется в UTF-8 и предваряется 32-битной длиной сообщения в порядке байтов собственного кода. Максимальный размер одного сообщения от собственного хоста обмена сообщениями составляет 1 МБ, главным образом для защиты Chrome от некорректной работы собственных приложений. Максимальный размер сообщения, отправляемого собственному хосту обмена сообщениями, составляет 64 МиБ.
Первым аргументом для нативного хоста обмена сообщениями является источник вызывающего абонента, обычно chrome-extension://[ID of allowed extension] . Это позволяет нативным хостам обмена сообщениями идентифицировать источник сообщения, когда в ключе allowed_origins в манифесте нативного хоста обмена сообщениями указано несколько расширений.
В Windows хосту обмена сообщениями также передается аргумент командной строки с дескриптором вызывающего окна Chrome: --parent-window=<decimal handle value> . Это позволяет хосту обмена сообщениями создавать окна пользовательского интерфейса, которые корректно связаны между собой. Обратите внимание, что это значение будет равно 0, если вызывающий контекст является сервисным рабочим процессом.
Когда порт для обмена сообщениями создается с помощью runtime.connectNative() Chrome запускает собственный процесс хоста обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage() без создания порта для обмена сообщениями, Chrome запускает новый собственный процесс хоста обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное процессом хоста, обрабатывается как ответ на исходный запрос, и Chrome передаст его в функцию обратного вызова ответа, указанную при вызове runtime.sendNativeMessage() . Все остальные сообщения, сгенерированные собственным хостом обмена сообщениями в этом случае, игнорируются.
Подключение к нативному приложению
Отправка и получение сообщений от нативного приложения очень похожи на обмен сообщениями между расширениями. Основное отличие заключается в том, что вместо runtime.connect() используется runtime.connectNative() , а вместо runtime.sendNativeMessage() runtime.sendMessage() .
Для использования этих методов необходимо указать разрешение "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);
}
);
Отладка встроенной системы обмена сообщениями
При возникновении определенных сбоев в работе встроенной системы обмена сообщениями, информация записывается в журнал ошибок Chrome. Это включает случаи, когда встроенная система обмена сообщениями не запускается, записывает данные в stderr или нарушает протокол связи. В Linux и macOS доступ к этому журналу можно получить, запустив Chrome из командной строки и просматривая его вывод в терминале. В Windows используйте --enable-logging как описано в разделе «Как включить ведение журнала» .
Вот несколько распространенных ошибок и советы по их исправлению:
Не удалось запустить собственный хост обмена сообщениями.
Проверьте, достаточно ли у вас прав для выполнения файла hosts, отвечающего за обмен сообщениями.
Указано недопустимое имя хоста для обмена сообщениями.
Проверьте, не содержит ли имя недопустимых символов. Допускаются только строчные буквенно-цифровые символы, символы подчеркивания и точки. Имя не может начинаться или заканчиваться точкой, и за точкой не может следовать другая точка.
Основной хост завершил работу.
Соединение с нативным мессенджером прервалось до того, как сообщение было прочитано Chrome. Вероятнее всего, это произошло по вине вашего нативного мессенджера.
Указанный собственный хост обмена сообщениями не найден.
Проверьте следующее:
- Правильно ли написано имя в расширении и в файле манифеста?
- Находится ли манифест в правильном каталоге и имеет ли он правильное имя? См. расположение нативного хоста обмена сообщениями для получения информации об ожидаемых форматах.
- Соответствует ли файл манифеста правильному формату? В частности, является ли JSON-файл корректным и правильно сформированным, и соответствуют ли значения определению манифеста нативного хоста обмена сообщениями ?
- Существует ли указанный в
pathфайл? В Windows пути могут быть относительными, но в macOS и Linux пути должны быть абсолютными.
Имя хоста , используемого в системе обмена сообщениями, не зарегистрировано. (Только для Windows)
В реестре Windows не найден собственный хост обмена сообщениями. Проверьте с помощью regedit , действительно ли был создан ключ и соответствует ли он требуемому формату, как указано в документации по расположению собственного хоста обмена сообщениями .
Доступ к указанному собственному серверу обмена сообщениями запрещен.
Указан ли источник расширения в файле allowed_origins ?
Ошибка при обмене данными с собственным сервером обмена сообщениями.
Это указывает на некорректную реализацию протокола связи в собственном хосте обмена сообщениями.
- Убедитесь, что весь вывод в
stdoutсоответствует собственному протоколу обмена сообщениями . Если вы хотите вывести какие-либо данные для отладки, записывайте их вstderr. - Убедитесь, что длина 32-битного сообщения указана в собственном целочисленном формате платформы (little-endian / big-endian).
- Длина сообщения не должна превышать 1024*1024.
- Размер сообщения должен быть равен количеству байтов в сообщении. Это может отличаться от «длины» строки, поскольку символы могут быть представлены несколькими байтами.
- Только для Windows: Убедитесь, что режим ввода-вывода программы установлен на
O_BINARY. По умолчанию режим ввода-вывода —O_TEXT, что искажает формат сообщения, поскольку переносы строк (\n=0A) заменяются символами конца строки в стиле Windows (\r\n=0D 0A). Режим ввода-вывода можно установить с помощью__setmode.