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

برنامه‌های افزودنی و برنامه‌ها می‌توانند با استفاده از یک 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 مسیر باینری میزبان پیام‌رسان بومی. در لینوکس و OSX مسیر باید مطلق باشد. در ویندوز می تواند نسبت به دایرکتوری که فایل مانیفست در آن قرار دارد باشد. فرآیند میزبان با دایرکتوری فعلی تنظیم شده روی دایرکتوری که حاوی باینری میزبان است شروع می شود. به عنوان مثال اگر این پارامتر روی C:\Application\nm_host.exe تنظیم شده باشد، با دایرکتوری فعلی C:\Application\ شروع می شود.
type نوع رابط مورد استفاده برای برقراری ارتباط با میزبان پیام رسانی بومی. در حال حاضر تنها یک مقدار ممکن برای این پارامتر وجود دارد: stdio . این نشان می دهد که Chrome باید از stdin و stdout برای برقراری ارتباط با میزبان استفاده کند.
allowed_origins لیست افزونه هایی که باید به میزبان پیام رسانی بومی دسترسی داشته باشند. حروف عامیانه مانند chrome-extension://*/* مجاز نیستند .

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

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

در ویندوز ، فایل مانیفست را می توان در هر نقطه از سیستم فایل قرار داد. نصب‌کننده برنامه باید کلید رجیستری HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ یا HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_ و مسیر پیش‌فرض my را روی مقدار پیش‌فرض، کلید my app_pan_com ایجاد کند. به فایل مانیفست برای مثال با استفاده از دستور زیر:

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"

وقتی کروم به دنبال میزبان‌های پیام‌رسان بومی می‌گردد، ابتدا رجیستری 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
  • لینوکس (در سطح سیستم)
    • 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
  • لینوکس (مسیر پیش فرض مختص کاربر)
    • 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 بیتی به ترتیب بایت بومی است. حداکثر اندازه یک پیام از میزبان پیام‌رسان بومی ۱ مگابایت است، که عمدتاً برای محافظت از Chrome در برابر برنامه‌های کاربردی بومی است. حداکثر اندازه پیام ارسال شده به میزبان پیام رسانی بومی 4 گیگابایت است.

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

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

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

اتصال به یک برنامه بومی

ارسال و دریافت پیام به و از یک برنامه بومی بسیار شبیه به پیام‌رسانی متقابل است. تفاوت اصلی این است که 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 می‌نویسد یا وقتی پروتکل ارتباطی را نقض می‌کند، خروجی در گزارش خطای Chrome نوشته می‌شود. در لینوکس و OS X، با راه اندازی کروم از خط فرمان و تماشای خروجی آن در ترمینال، به راحتی می توان به این گزارش دسترسی داشت. در ویندوز، از --enable-logging همانطور که در نحوه فعال کردن ورود به سیستم توضیح داده شده است استفاده کنید.

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

  • میزبان پیام‌رسانی بومی راه‌اندازی نشد.
    • بررسی کنید که آیا مجوزهای کافی برای اجرای فایل را دارید یا خیر.
  • نام میزبان پیام‌رسان بومی نامعتبر مشخص شده است.
    • بررسی کنید که آیا نام دارای نویسه های نامعتبر است یا خیر. فقط نویسه های حروف عددی کوچک، زیرخط و نقطه مجاز هستند. یک نام نمی تواند با یک نقطه شروع یا پایان یابد و یک نقطه نمی تواند با نقطه دیگری دنبال شود.
  • میزبان بومی خارج شده است.
    • لوله میزبان پیام‌رسان بومی قبل از خواندن پیام توسط کروم شکسته شد. این به احتمال زیاد از میزبان پیام رسانی بومی شما آغاز شده است.
  • میزبان پیام بومی مشخص شده یافت نشد.
    • آیا املای نام در پسوند و در فایل مانیفست به درستی نوشته شده است؟
    • آیا مانیفست در دایرکتوری درست و با نام صحیح قرار داده شده است؟ برای قالب‌های مورد انتظار ، مکان میزبان پیام‌رسانی بومی را ببینید.
    • آیا فایل مانیفست فرمت صحیحی دارد؟ به ویژه، آیا نحو JSON صحیح است و آیا مقادیر با تعریف مانیفست میزبان پیام‌رسان بومی مطابقت دارند؟
    • آیا فایل مشخص شده در path وجود دارد؟ در ویندوز، مسیرها ممکن است نسبی باشند، اما در OS X و لینوکس، مسیرها باید مطلق باشند.
  • نام میزبان پیام رسانی بومی ثبت نشده است. (فقط برای ویندوز)
    • میزبان پیام رسانی بومی در رجیستری ویندوز یافت نشد. با استفاده از regedit دوباره بررسی کنید که آیا کلید واقعاً ایجاد شده و با قالب مورد نیاز مطابق با مستند در مکان میزبان پیام‌رسانی بومی مطابقت دارد.
  • دسترسی به میزبان پیام بومی مشخص شده ممنوع است.
    • آیا مبدا برنامه افزودنی در allowed_origins ذکر شده است؟
  • خطا هنگام برقراری ارتباط با میزبان پیام‌رسان بومی.
    • این یک خطای بسیار رایج است و نشان دهنده اجرای نادرست پروتکل ارتباطی در میزبان پیام رسانی بومی است.
    • مطمئن شوید که تمام خروجی ها در stdout به پروتکل پیام رسانی بومی پایبند هستند. اگر می خواهید برخی از داده ها را برای اهداف اشکال زدایی چاپ کنید، در stderr بنویسید.
    • مطمئن شوید که طول پیام 32 بیتی در قالب اعداد صحیح اصلی پلتفرم (little-endian / big-endian) باشد.
    • طول پیام نباید از 1024*1024 تجاوز کند.
    • اندازه پیام باید برابر با تعداد بایت های پیام باشد. این ممکن است با "طول" یک رشته متفاوت باشد، زیرا کاراکترها ممکن است با چندین بایت نمایش داده شوند.
    • فقط ویندوز: مطمئن شوید که حالت I/O برنامه روی O_BINARY تنظیم شده باشد . به طور پیش‌فرض، حالت ورودی/خروجی O_TEXT است، که با جایگزینی خطوط شکسته‌های خط ( \n = 0A ) با پایان‌های خط به سبک ویندوز ( \r\n = 0D 0A ) قالب پیام را خراب می‌کند. حالت I/O را می توان با استفاده از __setmode تنظیم کرد.