העברת הודעות באפליקציות מקוריות

תוספים ואפליקציות יכולים להחליף הודעות עם אפליקציות מקוריות באמצעות ממשק 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 וב-OSX הנתיב חייב להיות מוחלט. ב-Windows, הקובץ יכול להיות יחסי לספרייה שבה נמצא קובץ המניפסט. התהליך של המארח מתחיל כשהספרייה הנוכחית מוגדרת לספרייה שמכילה את הקובץ הבינארי של המארח. לדוגמה, אם הערך של הפרמטר הזה הוא C:\Application\nm_host.exe, הוא יתחיל בספרייה הנוכחית C:\Application\.
typeסוג הממשק שמשמש לתקשורת עם מארח העברת ההודעות המקורי. נכון לעכשיו יש רק ערך אפשרי אחד לפרמטר הזה: stdio. המדיניות מציינת ש-Chrome צריך להשתמש ב-stdin וב-stdout כדי לתקשר עם המארח.
allowed_originsרשימת תוספים שצריכה להיות להם גישה למארח העברת ההודעות המקורי. אסור להשתמש בתווים כלליים לחיפוש כמו chrome-extension://*/*.

מיקום המארח להעברת הודעות נייטיב

המיקום של קובץ המניפסט תלוי בפלטפורמה.

ב-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 סיביות מרשם.

ב-OS X וב-Linux, המיקום של קובץ המניפסט של המארח להעברת הודעות נייטיב משתנה בהתאם בדפדפן (Google Chrome או Chromium). מתבצע חיפוש של המארחים להעברת הודעות נייטיב ברמת המערכת בעוד שמארחים להעברת הודעות נייטיב ברמת המשתמש מחפשים בספריית משנה ספריית פרופיל המשתמש בשם NativeMessagingHosts.

  • OS X (כל המערכת)
    • 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 (ספציפי למשתמש, נתיב ברירת המחדל)
    • 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 ביט אורך ההודעה לפי סדר הבייטים המקוריים. הגודל המקסימלי של הודעה בודדת מתוך המסר המקורי המארח הוא 1MB, בעיקר כדי להגן על Chrome מפני התנהגות לא תקינה של אפליקציות נייטיב. הגודל המקסימלי של הקוד הודעה שנשלחה למארח הודעות הנייטיב היא בגודל 4GB.

הארגומנט הראשון למארח העברת ההודעות המקומית הוא מקור המתקשר, בדרך כלל chrome-extension://[ID of allowed extension] כך מארחי ההודעות נייטיב יכולים לזהות מקור ההודעה כשמצוינים כמה תוספים במפתח allowed_origins ב מניפסט של מארח להעברת הודעות נייטיב. אזהרה: ב-Windows, ב-Chrome 54 ובגרסאות קודמות, המקור הועבר כפרמטר השני במקום הפרמטר הראשון.

כאשר יציאת העברת הודעות נוצרת באמצעות runtime.connectNative, Chrome מפעיל העברת הודעות נייטיב המארח. הוא ימשיך לפעול עד שהיציאה תושמד. לעומת זאת, כאשר הודעה נשלח באמצעות runtime.sendNativeMessage, בלי ליצור יציאת הודעות, Chrome מפעיל פקודה חדשה תהליך מארח העברת הודעות נייטיב לכל הודעה. במקרה הזה, ההודעה הראשונה שנוצרה על ידי המארח מטופל כתגובה לבקשה המקורית, כלומר Chrome יעביר אותה לתגובה מוגדרת קריאה חוזרת (callback) כאשר מתבצעת קריאה ל-runtime.sendNativeMessage. כל ההודעות האחרות שנוצרו על ידי במקרה כזה, המערכת מתעלמת מהמארח המקורי של העברת ההודעות.

ב-Windows, גם המארח להעברת הודעות נייטיב מועבר באמצעות ארגומנט של שורת הפקודה עם נקודת אחיזה קריאה לחלון המקורי של Chrome: --parent-window=<decimal handle value>. כך היא מאפשרת מארח העברת ההודעות יוצר חלונות של ממשק משתמש נייטיב עם הורה תקין. שימו לב שהערך הזה יהיה 0 אם ההקשר של הקריאה הוא דף של סקריפט רקע.

התחברות לאפליקציה מקורית

שליחה וקבלה של הודעות אל אפליקציית נייטיב דומה מאוד לשליחת הודעות בין תוספים העברת הודעות. ההבדל העיקרי הוא שנעשה שימוש ב-runtime.connectNative במקום ב- נעשה שימוש ב-runtime.connect וב-runtime.sendNativeMessage במקום runtime.sendMessage. ניתן להשתמש בשיטות האלה רק אם הרשאה מוצהרת באפליקציה שלכם קובץ מניפסט.

בדוגמה הבאה נוצר אובייקט runtime.Port שמחובר למארח העברת ההודעות במקור. com.my_company.my_application, מתחיל להקשיב להודעות מהיציאה הזו ושולח הודעה יוצאת אחת message:

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

ניפוי באגים באפליקציה להעברת הודעות נייטיב

כשמארח העברת ההודעות המקורית לא מצליח להתחיל, הוא כותב אל stderr או כשהוא מפר את פרוטוקול התקשורת, הפלט נכתב ביומן השגיאות של Chrome. ב-Linux וב-OS X, היומן הזה ניתן לגשת אליהם בקלות על ידי הפעלת Chrome משורת הפקודה וצפייה בפלט שלו ב נקודתיים. ב-Windows, משתמשים ב---enable-logging כמו שמוסבר במאמר איך מפעילים רישום ביומן.

ריכזנו כאן כמה שגיאות וטיפים לפתרון הבעיות:

  • לא ניתן להפעיל את המארח להעברת הודעות נייטיב.
    • בודקים אם יש לכם את ההרשאות המתאימות להפעלת הקובץ.
  • צוין שם מארח לא חוקי להעברת הודעות נייטיב.
    • בודקים אם השם מכיל תווים לא חוקיים. רק תווים אלפאנומריים, מותר להשתמש בקווים תחתונים ובנקודות. שם לא יכול להתחיל או להסתיים בנקודה, ולא יכול להיות נקודה ואחריה נקודה נוספת.
  • בוצעה יציאה מהמארח המקורי.
    • החיבור למארח העברת ההודעות הפנימי נשבר לפני ש-Chrome קרא את ההודעה. זה הכי כנראה ממארח ההודעות הנייטיב שלך.
  • המארח שצוין לצורך העברת הודעות נייטיב לא נמצא.
    • האם השם מאוית בצורה נכונה בתוסף ובקובץ המניפסט?
    • האם המניפסט נמצא בספרייה הנכונה ועם השם הנכון? למידע נוסף, ראו מארח של העברת הודעות מותאמת אישית לפורמטים הרצויים.
    • האם קובץ המניפסט בפורמט הנכון? באופן ספציפי, האם התחביר של JSON תקין תואמים להגדרה של מניפסט של מארח להעברת הודעות נייטיב?
    • האם הקובץ שצוין ב-path קיים? ב-Windows, הנתיבים עשויים להיות יחסיים, אבל ב-OS X וב-Linux, הנתיבים חייבים להיות מוחלטים.
  • שם המארח של המארח להעברת הודעות נייטיב לא רשום. (Windows בלבד)
  • הגישה למארח העברת ההודעות המקורי שצוין אסורה.
    • האם מקור התוסף מופיע בallowed_origins?
  • שגיאה בתקשורת עם המארח של העברת ההודעות המקורית.
    • זוהי שגיאה נפוצה מאוד שמרמזת על יישום שגוי של פרוטוקול התקשורת מארח העברת ההודעות המקור.
    • יש לוודא שכל הפלט ב-stdout תואם לפרוטוקול להעברת הודעות נייטיב. אם רוצים כדי להדפיס נתונים מסוימים למטרות ניפוי באגים, יש לכתוב אל stderr.
    • צריך לוודא שאורך ההודעה של 32 ביט הוא בפורמט המספרים השלמים המותאמים (Lite-endian) של הפלטפורמה / Big-endian).
    • אורך ההודעה לא יכול לחרוג מ-1024*1024.
    • גודל ההודעה חייב להיות שווה למספר הבייטים בהודעה. כתובת ה-URL הזו עשויה להיות שונה 'length' של מחרוזת, כי תווים יכולים להיות מיוצגים על ידי מספר בייטים.
    • Windows בלבד: מוודאים שמצב הקלט/פלט של התוכנה מוגדר ל-O_BINARY. כברירת מחדל, קלט/פלט (I/O) המצב הוא O_TEXT, מה שפוגם בפורמט ההודעה כשמעברי שורה (\n = 0A) מוחלפים ב- סיומות שורות בסגנון Windows (\r\n = 0D 0A). אפשר להגדיר את מצב קלט/פלט (I/O) באמצעות __setmode.