پیام‌رسانی بومی

افزونه‌ها می‌توانند با استفاده از یک API که مشابه سایر APIهای انتقال پیام است، با برنامه‌های بومی پیام رد و بدل کنند. برنامه‌های بومی که از این ویژگی پشتیبانی می‌کنند، باید یک میزبان پیام‌رسانی بومی ثبت کنند که بتواند با افزونه ارتباط برقرار کند. کروم میزبان را در یک فرآیند جداگانه شروع می‌کند و با استفاده از جریان‌های ورودی و خروجی استاندارد با آن ارتباط برقرار می‌کند.

میزبان پیام‌رسانی بومی

برای ثبت یک میزبان پیام‌رسانی بومی، برنامه باید فایلی را ذخیره کند که پیکربندی میزبان پیام‌رسانی بومی را تعریف می‌کند.

نمونه‌ای از فایل به صورت زیر است:

{
  "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
مسیر به فایل باینری میزبان پیام‌رسانی بومی. در لینوکس و macOS، مسیر باید مطلق باشد. در ویندوز می‌تواند نسبت به دایرکتوری حاوی فایل مانیفست باشد. فرآیند میزبان با دایرکتوری فعلی که روی دایرکتوری حاوی فایل باینری میزبان تنظیم شده است، آغاز می‌شود. برای مثال، اگر این پارامتر روی C:\Application\nm_host.exe تنظیم شود، با دایرکتوری فعلی `C:\Application` آغاز خواهد شد.
type
نوع رابط مورد استفاده برای ارتباط با میزبان پیام‌رسانی بومی. این پارامتر یک مقدار ممکن دارد: stdio . این نشان می‌دهد که کروم باید stdin و stdout برای ارتباط با میزبان استفاده کند.
allowed_origins
فهرست افزونه‌هایی که باید به میزبان پیام‌رسانی بومی دسترسی داشته باشند. مقادیر allowed-origins نمی‌توانند شامل کاراکترهای جایگزین باشند.

موقعیت مکانی میزبان پیام‌رسانی بومی

محل قرارگیری فایل مانیفست به پلتفرم بستگی دارد.

در ویندوز ، فایل مانیفست می‌تواند در هر جایی از سیستم فایل قرار داشته باشد. نصب‌کننده برنامه باید یک کلید رجیستری ایجاد کند، یا 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"

وقتی کروم به دنبال میزبان‌های پیام‌رسان بومی می‌گردد، ابتدا رجیستری ۳۲ بیتی و سپس رجیستری ۶۴ بیتی جستجو می‌شود.

در macOS و لینوکس ، محل فایل مانیفست میزبان پیام‌رسانی بومی بسته به مرورگر (گوگل کروم یا کرومیوم) متفاوت است. میزبان‌های پیام‌رسانی بومی در سطح سیستم در یک مکان ثابت جستجو می‌شوند، در حالی که میزبان‌های پیام‌رسانی بومی در سطح کاربر در زیرشاخه NativeMessagingHosts/ از فهرست نمایه کاربر جستجو می‌شوند.

macOS (در سطح سیستم)
گوگل کروم: /Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
کرومیوم: /Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
macOS (مسیر پیش‌فرض ، مختص کاربر)
گوگل کروم: ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
کرومیوم: ~/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
لینوکس (در سطح سیستم)
گوگل کروم: /etc/opt/chrome/native-messaging-hosts/com.my_company.my_application.json
کرومیوم: /etc/chromium/native-messaging-hosts/com.my_company.my_application.json
لینوکس (مسیر پیش‌فرض ، مختص کاربر)
گوگل کروم: ~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json
کرومیوم: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

پروتکل پیام‌رسانی بومی

کروم هر میزبان پیام‌رسانی بومی را در یک فرآیند جداگانه شروع می‌کند و با استفاده از ورودی استاندارد ( stdin ) و خروجی استاندارد ( stdout ) با آن ارتباط برقرار می‌کند. از قالب یکسانی برای ارسال پیام‌ها در هر دو جهت استفاده می‌شود؛ هر پیام با استفاده از JSON و کدگذاری UTF-8 سریالی می‌شود و قبل از آن پیام با طول ۳۲ بیت و به ترتیب بایت بومی ارسال می‌شود. حداکثر اندازه یک پیام از میزبان پیام‌رسانی بومی ۱ مگابایت است، که عمدتاً برای محافظت از کروم در برابر سوء رفتار برنامه‌های بومی است. حداکثر اندازه پیام ارسالی به میزبان پیام‌رسانی بومی ۶۴ مگابایت است.

اولین آرگومان برای میزبان پیام‌رسانی بومی، مبدأ فراخوانی‌کننده است که معمولاً chrome-extension://[ID of allowed extension] . این به میزبان‌های پیام‌رسانی بومی اجازه می‌دهد تا منبع پیام را هنگامی که چندین افزونه در کلید allowed_origins در مانیفست میزبان پیام‌رسانی بومی مشخص شده‌اند، شناسایی کنند.

در ویندوز، به میزبان پیام‌رسانی بومی، یک آرگومان خط فرمان به همراه یک هندل به پنجره بومی کرومِ در حال فراخوانی نیز ارسال می‌شود: --parent-window=<decimal handle value> . این به میزبان پیام‌رسانی بومی اجازه می‌دهد تا پنجره‌های رابط کاربری بومی ایجاد کند که به درستی والد شده‌اند. توجه داشته باشید که اگر زمینه فراخوانی یک سرویس ورکر باشد، این مقدار 0 خواهد بود.

وقتی یک پورت پیام‌رسانی با استفاده از runtime.connectNative() ایجاد می‌شود، کروم فرآیند میزبان پیام‌رسانی بومی را شروع می‌کند و آن را تا زمانی که پورت از بین برود، در حال اجرا نگه می‌دارد. از سوی دیگر، وقتی پیامی با استفاده از runtime.sendNativeMessage() ارسال می‌شود، بدون ایجاد پورت پیام‌رسانی، کروم برای هر پیام، یک فرآیند میزبان پیام‌رسانی بومی جدید را شروع می‌کند. در این صورت، اولین پیام تولید شده توسط فرآیند میزبان به عنوان پاسخی به درخواست اصلی مدیریت می‌شود و کروم آن را به تابع فراخوانی پاسخ مشخص شده هنگام فراخوانی 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);
  }
);

اشکال‌زدایی پیام‌های بومی

وقتی برخی از خطاهای پیام‌رسانی بومی رخ می‌دهد، خروجی در گزارش خطای کروم نوشته می‌شود. این شامل مواردی می‌شود که میزبان پیام‌رسانی بومی نتواند شروع به کار کند، در stderr بنویسد یا پروتکل ارتباطی را نقض کند. در لینوکس و macOS، با شروع کروم از خط فرمان و مشاهده خروجی آن در ترمینال، می‌توان به این گزارش دسترسی پیدا کرد. در ویندوز، از --enable-logging همانطور که در نحوه فعال کردن گزارش‌گیری توضیح داده شده است، استفاده کنید.

در اینجا چند خطای رایج و نکاتی برای حل آنها آورده شده است:

میزبان پیام‌رسانی بومی راه‌اندازی نشد.

بررسی کنید که آیا مجوزهای کافی برای اجرای فایل میزبان پیام‌رسانی بومی را دارید یا خیر.

نام میزبان پیام‌رسانی داخلی نامعتبر مشخص شده است.

بررسی کنید که آیا نام شامل کاراکترهای نامعتبر است یا خیر. فقط کاراکترهای حروف کوچک، زیرخط و نقطه مجاز هستند. نام نمی‌تواند با نقطه شروع یا پایان یابد و پس از نقطه نمی‌توان نقطه دیگری قرار داد.

میزبان بومی خارج شده است.

قبل از اینکه پیام توسط کروم خوانده شود، ارتباط با میزبان پیام‌رسانی بومی قطع شده است. این مشکل به احتمال زیاد از میزبان پیام‌رسانی بومی شما آغاز شده است.

میزبان پیام‌رسانی بومی مشخص‌شده یافت نشد.

موارد زیر را بررسی کنید:

  • آیا نام در افزونه و فایل مانیفست به درستی نوشته شده است؟
  • آیا مانیفست در دایرکتوری صحیح و با نام صحیح است؟ برای اطلاع از فرمت‌های مورد انتظار، به محل میزبان پیام‌رسانی بومی مراجعه کنید.
  • آیا فایل مانیفست در قالب صحیح است؟ به طور خاص، آیا JSON معتبر و خوش‌فرم است و آیا مقادیر آن با تعریف مانیفست میزبان پیام‌رسانی بومی مطابقت دارد؟
  • آیا فایل مشخص شده در path وجود دارد؟ در ویندوز، مسیرها می‌توانند نسبی باشند، اما در macOS و لینوکس، مسیرها باید مطلق باشند.

نام میزبان پیام‌رسانی بومی ثبت نشده است. (فقط ویندوز)

میزبان پیام‌رسانی بومی در رجیستری ویندوز یافت نشد. با استفاده از regedit بررسی کنید که آیا کلید واقعاً ایجاد شده است و با فرمت مورد نیاز مطابق با آنچه در محل میزبان پیام‌رسانی بومی مستند شده است، مطابقت دارد.

دسترسی به میزبان پیام‌رسانی بومی مشخص‌شده ممنوع است.

آیا مبدا افزونه در allowed_origins فهرست شده است؟

خطا هنگام برقراری ارتباط با میزبان پیام‌رسانی بومی.

این نشان دهنده اجرای نادرست پروتکل ارتباطی در میزبان پیام رسانی بومی است.

  • مطمئن شوید که تمام خروجی‌های stdout به پروتکل پیام‌رسانی بومی پایبند هستند. اگر می‌خواهید برخی داده‌ها را برای اهداف اشکال‌زدایی چاپ کنید، در stderr بنویسید.
  • مطمئن شوید که طول پیام ۳۲ بیتی در قالب عدد صحیح بومی پلتفرم (little-endian / big-endian) باشد.
  • طول پیام نباید از 1024*1024 بیشتر شود.
  • اندازه پیام باید برابر با تعداد بایت‌های موجود در پیام باشد. این ممکن است با "طول" یک رشته متفاوت باشد، زیرا کاراکترها ممکن است توسط چندین بایت نمایش داده شوند.
  • فقط ویندوز: مطمئن شوید که حالت ورودی/خروجی برنامه روی O_BINARY تنظیم شده است. به طور پیش‌فرض، حالت ورودی/خروجی O_TEXT است که با جایگزینی شکست خط‌ها ( \n = 0A ) با انتهای خط‌های به سبک ویندوز ( \r\n = 0D 0A )، فرمت پیام را خراب می‌کند. حالت ورودی/خروجی را می‌توان با استفاده از __setmode تنظیم کرد.