Расширения могут обмениваться сообщениями с нативными приложениями, используя 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 или Chromium). Поиск собственных хостов обмена сообщениями на уровне всей системы осуществляется в фиксированном месте, а поиск собственных хостов обмена сообщениями на уровне пользователя — в подкаталоге NativeMessagingHosts/ каталога профиля пользователя .
- macOS (общесистемная)
- 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 (пользовательский путь по умолчанию )
- 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 - 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 - 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 как описано в статье «Как включить ведение журнала» .
Вот некоторые распространённые ошибки и советы по их решению:
Не удалось запустить собственный хост обмена сообщениями.
Проверьте, есть ли у вас достаточные разрешения для выполнения файла хоста собственного обмена сообщениями.
Указано неверное имя хоста для обмена сообщениями.
Проверьте имя на наличие недопустимых символов. Допускаются только строчные буквы, цифры, символы подчёркивания и точки. Имя не может начинаться или заканчиваться точкой, а за точкой не может следовать другая точка.
Родной хост вышел из строя.
Канал к нативному хосту обмена сообщениями был оборван до того, как сообщение было прочитано 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.