Расширения могут обмениваться сообщениями с собственными приложениями, используя 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
- Хром:
/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: --parent-window=<decimal handle value>
. Это позволяет собственному узлу обмена сообщениями создавать собственные окна пользовательского интерфейса, которые правильно являются родительскими. Обратите внимание, что это значение будет равно 0, если вызывающим контекстом является сервисный работник.
Когда порт обмена сообщениями создается с помощью runtime.connectNative()
Chrome запускает собственный хост-процесс обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage()
без создания порта обмена сообщениями, Chrome запускает новый собственный хост-процесс обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное хост-процессом, обрабатывается как ответ на исходный запрос, и Chrome передает его обратному вызову ответа, указанному при вызове runtime.sendNativeMessage()
. Все остальные сообщения, генерируемые собственным узлом обмена сообщениями, в этом случае игнорируются.
Подключение к родному приложению
Отправка и получение сообщений в собственное приложение и из него очень похоже на обмен сообщениями между расширениями. Основное отличие состоит в том, что вместо runtime.connectNative()
используется runtime.connect()
, а вместо 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
.