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

برنامه های افزودنی می توانند با استفاده از یک 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 . این نشان می دهد که Chrome باید 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"

وقتی کروم به دنبال میزبان‌های پیام‌رسان بومی می‌گردد، ابتدا رجیستری 32 بیتی و سپس رجیستری 64 بیتی جستجو می‌شود.

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

macOS (در سراسر سیستم)
Google Chrome: /Library/Google/Chrome/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
Chromium: ~/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
لینوکس (مسیر پیش فرض مختص کاربر)
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 در مانیفست میزبان پیام‌رسان بومی مشخص شده‌اند.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

میزبان پیام رسانی بومی در رجیستری ویندوز یافت نشد. با استفاده از 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 تنظیم کرد.