תוספים יכולים להחליף הודעות עם אפליקציות מקומיות באמצעות 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 for Testing או Chromium). מארחים ברמת המערכת להעברת הודעות באפליקציות מקוריות נבדקים במיקום קבוע, ומארחים ברמת המשתמש להעברת הודעות באפליקציות מקוריות נבדקים בספריית המשנה NativeMessagingHosts/ של ספריית פרופיל המשתמש.
- macOS (כלל המערכת)
- Google Chrome:
/Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
- Google Chrome for Testing:
/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 for Testing:
~/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 for Testing:
/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 for Testing:
~/.config/google-chrome-for-testing/NativeMessagingHosts/com.my_company.my_application.json
- Chromium:
~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json
פרוטוקול להעברת הודעות נייטיב
Chrome מפעיל כל מארח להעברת הודעות נייטיב בתהליך נפרד, ומתקשר איתו באמצעות קלט סטנדרטי (stdin) (stdin) ופלט סטנדרטי (stdout) (stdout). נעשה שימוש באותו פורמט לשליחת הודעות בשני הכיוונים. כל הודעה עוברת סריאליזציה באמצעות JSON, מקודדת ב-UTF-8 ומקדימה אותה אורך ההודעה ב-32 ביט בסדר הבתים המקורי. הגודל המקסימלי של הודעה יחידה ממארח להעברת הודעות נייטיב הוא 1MB, בעיקר כדי להגן על Chrome מפני אפליקציות נייטיב שמתנהגות בצורה לא תקינה. הגודל המקסימלי של ההודעה שנשלחת למארח להעברת הודעות נייטיב הוא 64MiB.
הארגומנט הראשון למארח להעברת הודעות נייטיב הוא המקור של המתקשר, בדרך כלל 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.sendMessage() משתמשים ב-runtime.sendNativeMessage().
כדי להשתמש בשיטות האלה, צריך להצהיר על ההרשאה 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 ביט הוא בפורמט המספרים המקורי של הפלטפורמה (little-endian / big-endian).
- אורך ההודעה לא יכול להיות יותר מ-1,048,576 תווים.
- גודל ההודעה צריך להיות שווה למספר הבייטים בהודעה. יכול להיות שהערך הזה יהיה שונה מהערך של 'אורך' של מחרוזת, כי יכול להיות שתווים מיוצגים על ידי כמה בייטים.
- ב-Windows בלבד: מוודאים שמצב הקלט/פלט של התוכנית מוגדר ל-
O_BINARY. כברירת מחדל, מצב הקלט/פלט הואO_TEXT, שגורם לשיבוש בפורמט ההודעה כי מעברי שורה (\n=0A) מוחלפים בסיומי שורה בסגנון Windows (\r\n=0D 0A). אפשר להגדיר את מצב הקלט/פלט באמצעות__setmode.