Wiadomości natywne

Rozszerzenia i aplikacje mogą wymieniać wiadomości z aplikacjami natywnymi przy użyciu interfejsu API podobnego do innych interfejsów API przekazujących wiadomości. Aplikacje natywne, które obsługują tę funkcję, muszą zarejestrować host natywnego przesyłania komunikatów, który wie, jak komunikować się z rozszerzeniem. Chrome uruchamia hosta w osobnym procesie i komunikuje się z nim za pomocą standardowych strumieni wejściowych i standardowych.

Host natywnego przesyłania komunikatów

Aby można było zarejestrować hosta natywnego przesyłania wiadomości, aplikacja musi zainstalować plik manifestu, który określa konfigurację hosta natywnego przesyłania komunikatów. Poniżej znajduje się przykład pliku manifestu:

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

Plik manifestu hosta natywnego przesyłania komunikatów musi mieć prawidłowy format JSON i zawierać te pola:

NazwaOpis
nameNazwa hosta natywnego przesyłania komunikatów. Klienty przekazują ten ciąg znaków do metody runtime.connectNative lub runtime.sendNativeMessage. Ta nazwa może zawierać tylko małe znaki alfanumeryczne, podkreślenia i kropki. Nazwa nie może zaczynać się ani kończyć kropką, a po kropce nie może następować inna kropka.
descriptionKrótki opis aplikacji.
pathŚcieżka do pliku binarnego hosta natywnego przesyłania wiadomości. W systemach Linux i OS X ścieżka musi być bezwzględna. W systemie Windows może on być zależny od katalogu, w którym znajduje się plik manifestu. Proces hosta jest uruchamiany z bieżącym katalogiem ustawionym na katalog zawierający plik binarny hosta. Jeśli np. ten parametr ma wartość C:\Application\nm_host.exe, zostanie uruchomiony w bieżącym katalogu C:\Application\.
typeTyp interfejsu używany do komunikacji z hostem natywnego przesyłania komunikatów. Obecnie ten parametr może mieć tylko jedną wartość: stdio. Wskazuje ona, że do komunikacji z hostem Chrome powinien używać stdin i stdout.
allowed_originsLista rozszerzeń, które powinny mieć dostęp do hosta wiadomości natywnych. Symbole wieloznaczne, takie jak chrome-extension://*/*, są niedozwolone.

Lokalizacja hosta komunikatora natywnego

Lokalizacja pliku manifestu zależy od platformy.

W systemie Windows plik manifestu możesz umieścić w dowolnym miejscu w systemie plików. Instalator aplikacji musi utworzyć klucz rejestru HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ lub HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ i ustawić domyślną wartość tego klucza na pełną ścieżkę do pliku manifestu. Na przykład za pomocą tego polecenia:

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

lub za pomocą tego pliku .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"

Gdy Chrome szuka hostów wiadomości natywnych, najpierw wysyłane jest zapytanie do rejestru 32-bitowego, a następnie do rejestru 64-bitowego.

W systemach OS X i Linux lokalizacja pliku manifestu natywnego hosta wiadomości różni się w zależności od przeglądarki (Google Chrome lub Chromium). Hosty natywnych aplikacji do obsługi wiadomości w całym systemie są sprawdzane w stałej lokalizacji, natomiast hosty wiadomości natywnych na poziomie użytkownika są przeszukiwane w podkatalogu katalogu profilu użytkownika o nazwie NativeMessagingHosts.

  • OS X (cały system)
    • 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 (ścieżka domyślna, która jest specyficzna dla użytkownika)
    • 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 (w całym systemie)
    • 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 (ścieżka domyślna, która jest specyficzna dla użytkownika)
    • Google Chrome: ~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: ~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

Protokół natywnego przesyłania komunikatów

Chrome uruchamia każdy host natywnego przesyłania komunikatów w osobnym procesie i komunikuje się z nim za pomocą standardowych danych wejściowych (stdin) i standardowych danych wyjściowych (stdout). Ten sam format jest używany do wysyłania wiadomości w obu kierunkach: każda wiadomość jest serializowana w formacie JSON, zakodowana UTF-8 i jest poprzedzona 32-bitową długością wiadomości w natywnej kolejności bajtów. Maksymalny rozmiar pojedynczej wiadomości pochodzącej z hosta natywnego przesyłania wiadomości wynosi 1 MB. Głównie w celu ochrony Chrome przed nieodpowiednimi aplikacjami natywnymi. Maksymalny rozmiar wiadomości wysyłanej do hosta natywnego przesyłania wiadomości wynosi 4 GB.

Pierwszym argumentem hosta wiadomości natywnych to pochodzenie elementu wywołującego, zwykle chrome-extension://[ID of allowed extension]. Dzięki temu hosty natywnych aplikacji do obsługi wiadomości mogą zidentyfikować źródło wiadomości, gdy klucz allowed_origins w pliku manifestu hosta natywnego czatu zawiera wiele rozszerzeń. Ostrzeżenie: w systemie Windows w Chrome 54 i starszych wersjach źródło było przekazywane jako drugi parametr, a nie pierwszy.

Po utworzeniu portu do przesyłania wiadomości za pomocą metody runtime.connectNative Chrome uruchamia natywny proces hosta do obsługi wiadomości i nie wyłącza go do czasu jego zniszczenia. Z drugiej strony, gdy wiadomość jest wysyłana za pomocą metody runtime.sendNativeMessage bez utworzenia portu do obsługi wiadomości, Chrome uruchamia nowy proces hosta natywnego przesyłania komunikatów dla każdej wiadomości. W takim przypadku pierwszy komunikat wygenerowany przez proces hosta jest traktowany jako odpowiedź na pierwotne żądanie, tj. Chrome przekazuje ją do wywołania zwrotnego określonego po wywołaniu funkcji runtime.sendNativeMessage. Wszystkie pozostałe wiadomości wygenerowane przez hosta natywnego przesyłania komunikatów w takim przypadku będą ignorowane.

W systemie Windows host natywnego przesyłania komunikatów otrzymuje też argument wiersza poleceń z nickem wywołującym okno natywne Chrome: --parent-window=<decimal handle value>. Dzięki temu host natywnego komunikatów głosowych może tworzyć okna interfejsu natywne, które mają prawidłowe elementy nadrzędne. Pamiętaj, że jeśli kontekst wywołania to strona skryptu w tle, ta wartość będzie wynosić 0.

Nawiązywanie połączenia z aplikacją natywną

Wysyłanie i odbieranie wiadomości do i z aplikacji natywnej jest bardzo podobne do przesyłania wiadomości w różnych rozszerzeniach. Główna różnica polega na tym, że zamiast elementu runtime.connect jest używana metoda runtime.connectNative, a zamiast niej runtime.sendMessage używany jest tag runtime.sendNativeMessage. Tych metod można używać tylko wtedy, gdy uprawnienie „nativeMessaging” jest zadeklarowane w pliku manifestu aplikacji.

Poniższy przykład pokazuje: tworzy obiekt runtime.Port połączony z hostem natywnego przesyłania komunikatów com.my_company.my_application, zaczyna nasłuchiwać wiadomości z tego portu i wysyła 1 wiadomość wychodzącą:

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" });

Metoda runtime.sendNativeMessage może służyć do wysyłania wiadomości do aplikacji natywnej bez tworzenia portu, na przykład:

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

Debugowanie komunikatów natywnych

Gdy host natywnego przesyłania wiadomości nie uruchamia się, zapisuje dane w stderr lub jeśli narusza protokół komunikacji, w dzienniku błędów Chrome są zapisywane dane wyjściowe. W systemach Linux i OS X ten dziennik można łatwo uzyskać, uruchamiając Chrome z poziomu wiersza poleceń i obserwując dane wyjściowe w terminalu. W systemie Windows użyj --enable-logging zgodnie z opisem w artykule Jak włączyć logowanie.

Oto kilka błędów i wskazówki, które pomogą Ci rozwiązać te problemy:

  • Nie udało się uruchomić hosta natywnego przesyłania wiadomości.
    • Sprawdź, czy masz wystarczające uprawnienia do wykonania pliku.
  • Podano nieprawidłową nazwę hosta wiadomości natywnych.
    • Sprawdź, czy nazwa zawiera nieprawidłowe znaki. Dozwolone są tylko małe znaki alfanumeryczne, podkreślenia i kropki. Nazwa nie może zaczynać się ani kończyć kropką, a po kropce nie może być inna kropka.
  • Host natywny został zamknięty.
    • Pionowa kreska do hosta komunikatora natywnego uległa uszkodzeniu przed odczytaniem wiadomości przez Chrome. Najczęściej inicj ten pochodzi z hosta natywnego przesyłania komunikatów.
  • Nie znaleziono określonego hosta wiadomości natywnych.
    • Czy nazwa jest poprawnie napisana w rozszerzeniu i w pliku manifestu?
    • Czy plik manifestu znajduje się w odpowiednim katalogu i ma prawidłową nazwę? Odpowiednie formaty znajdziesz w sekcji Lokalizacja hosta komunikatora natywnego.
    • Czy plik manifestu ma prawidłowy format? W szczególności chodzi o to, czy składnia JSON jest prawidłowa i czy wartości pasują do definicji pliku manifestu hosta natywnego przesyłania komunikatów.
    • Czy plik określony w polu path istnieje? W systemie Windows ścieżki mogą być względne, a w systemach OS X i Linux ścieżki bezwzględne.
  • Nazwa hosta hosta komunikatora natywnego nie jest zarejestrowana. (tylko system Windows)
    • Nie znaleziono hosta natywnego przesyłania komunikatów w rejestrze systemu Windows. Korzystając z metody regedit, sprawdź dokładnie, czy klucz został rzeczywiście utworzony i czy pasuje do wymaganego formatu, co jest zgodne z lokalizacją hosta natywnego przekazu.
  • Dostęp do określonego hosta wiadomości natywnych jest zabroniony.
    • Czy źródło rozszerzenia jest podane w: allowed_origins?
  • Podczas komunikowania się z hostem natywnego przesyłania wiadomości wystąpił błąd.
    • Jest to bardzo częsty błąd, który wskazuje na nieprawidłową implementację protokołu komunikacyjnego na hoście natywnego przesyłania wiadomości.
    • Upewnij się, że wszystkie dane wyjściowe w usłudze stdout są zgodne z protokołem natywnego przesyłania wiadomości. Jeśli chcesz wydrukować niektóre dane do celów debugowania, wpisz je na stronie stderr.
    • Upewnij się, że 32-bitowa długość komunikatu jest zapisana w natywnym formacie liczb całkowitych dostępnych na platformie (little-endian/big-endian).
    • Długość wiadomości nie może przekraczać 1024*1024.
    • Rozmiar wiadomości musi być równy liczbie bajtów tej wiadomości. Ta wartość może różnić się od „długości” ciągu znaków, ponieważ znaki mogą być reprezentowane przez wiele bajtów.
    • Tylko w systemie Windows: sprawdź, czy tryb wejścia-wyjścia programu jest ustawiony na O_BINARY. Domyślnie tryb wejścia/wyjścia to O_TEXT, co powoduje uszkodzenie formatu wiadomości, ponieważ podziały wierszy (\n = 0A) są zastępowane zakończeniami wierszy w stylu Windows (\r\n = 0D 0A). Tryb wejścia-wyjścia można ustawić, używając elementu __setmode.