Расширения могут обмениваться сообщениями с собственными приложениями, используя 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, если вызывающий контекст — это service worker.
Когда порт обмена сообщениями создается с помощью runtime.connectNative()
Chrome запускает собственный процесс хоста обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage()
, без создания порта обмена сообщениями, Chrome запускает новый собственный процесс хоста обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное процессом хоста, обрабатывается как ответ на исходный запрос, и Chrome передаст его обратному вызову ответа, указанному при вызове runtime.sendNativeMessage()
. Все остальные сообщения, сгенерированные собственным хостом обмена сообщениями в этом случае, игнорируются.
Подключение к собственному приложению
Отправка и получение сообщений в и из собственного приложения очень похожи на обмен сообщениями между расширениями. Главное отличие в том, что вместо runtime.connect runtime.connectNative()
используется runtime.connect()
, а вместо runtime.sendNativeMessage()
используется runtime.sendMessage()
.
Для использования этих методов необходимо объявить разрешение «nativeMessaging» в файле манифеста вашего расширения.
Эти методы недоступны внутри скриптов контента, только внутри страниц вашего расширения и service worker. Если вы хотите связаться из скрипта контента с собственным приложением, отправьте сообщение вашему service worker, чтобы передать его собственному приложению.
В следующем примере создается объект 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 бита) соответствует собственному целочисленному формату платформы (от младшего к старшему / от старшего к старшему).
- Длина сообщения не должна превышать 1024*1024.
- Размер сообщения должен быть равен количеству байтов в сообщении. Это может отличаться от «длины» строки, поскольку символы могут быть представлены несколькими байтами.
- Только для Windows: убедитесь, что режим ввода-вывода программы установлен на
O_BINARY
. По умолчанию режим ввода-вывода —O_TEXT
, что искажает формат сообщения, поскольку переносы строк (\n
=0A
) заменяются окончаниями строк в стиле Windows (\r\n
=0D 0A
). Режим ввода-вывода можно установить с помощью__setmode
.