নেটিভ মেসেজিং

এক্সটেনশনগুলো অন্যান্য মেসেজ পাসিং এপিআই-এর মতো একটি এপিআই ব্যবহার করে নেটিভ অ্যাপ্লিকেশনগুলোর সাথে বার্তা আদান-প্রদান করতে পারে। যে নেটিভ অ্যাপ্লিকেশনগুলো এই বৈশিষ্ট্যটি সমর্থন করে, সেগুলোকে অবশ্যই একটি নেটিভ মেসেজিং হোস্ট নিবন্ধন করতে হবে যা এক্সটেনশনটির সাথে যোগাযোগ করতে পারে। ক্রোম একটি পৃথক প্রসেসে হোস্টটি চালু করে এবং স্ট্যান্ডার্ড ইনপুট ও স্ট্যান্ডার্ড আউটপুট স্ট্রিম ব্যবহার করে এর সাথে যোগাযোগ করে।

স্থানীয় মেসেজিং হোস্ট

একটি নেটিভ মেসেজিং হোস্ট নিবন্ধন করতে হলে, অ্যাপ্লিকেশনটিকে অবশ্যই একটি ফাইল সংরক্ষণ করতে হবে যা নেটিভ মেসেজিং হোস্টের কনফিগারেশন নির্ধারণ করে।

ফাইলটির একটি উদাহরণ নিচে দেওয়া হলো:

{
  "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
নেটিভ মেসেজিং হোস্ট বাইনারির পাথ। লিনাক্স এবং ম্যাকওএস-এ পাথটি অবশ্যই অ্যাবসোলিউট হতে হবে। উইন্ডোজে এটি ম্যানিফেস্ট ফাইল ধারণকারী ডিরেক্টরির সাপেক্ষে রিলেটিভ হতে পারে। হোস্ট প্রসেসটি হোস্ট বাইনারি ধারণকারী ডিরেক্টরিকে কারেন্ট ডিরেক্টরি হিসেবে সেট করে চালু করা হয়। উদাহরণস্বরূপ, যদি এই প্যারামিটারটি 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"

ক্রোম যখন নেটিভ মেসেজিং হোস্ট খোঁজে, তখন প্রথমে ৩২-বিট রেজিস্ট্রি এবং তারপর ৬৪-বিট রেজিস্ট্রি কোয়েরি করা হয়।

macOS এবং Linux- এ, নেটিভ মেসেজিং হোস্টের ম্যানিফেস্ট ফাইলের অবস্থান ব্রাউজার (Google Chrome, Google Chrome for Testing বা Chromium) অনুযায়ী ভিন্ন হয়। সিস্টেম-ব্যাপী নেটিভ মেসেজিং হোস্টগুলো একটি নির্দিষ্ট স্থানে খোঁজা হয়, অন্যদিকে ব্যবহারকারী-স্তরের নেটিভ মেসেজিং হোস্টগুলো ব্যবহারকারীর প্রোফাইল ডিরেক্টরির NativeMessagingHosts/ সাবডিরেক্টরিতে খোঁজা হয়।

ম্যাকওএস (সিস্টেম-ব্যাপী)
গুগল ক্রোম: /Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
পরীক্ষার জন্য গুগল ক্রোম: /Library/Google/ChromeForTesting/NativeMessagingHosts/com.my_company.my_application.json
ক্রোমিয়াম: /Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json
ম্যাকওএস (ব্যবহারকারী-নির্দিষ্ট, ডিফল্ট পথ)
গুগল ক্রোম: ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
পরীক্ষার জন্য গুগল ক্রোম: ~/Library/Application Support/Google/ChromeForTesting/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/opt/chrome_for_testing/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/google-chrome-for-testing/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> । এটি নেটিভ মেসেজিং হোস্টকে সঠিকভাবে প্যারেন্টেড নেটিভ UI উইন্ডো তৈরি করতে দেয়। উল্লেখ্য যে, কলিং কনটেক্সট যদি একটি সার্ভিস ওয়ার্কার হয়, তাহলে এই মানটি 0 হবে।

যখন runtime.connectNative() ব্যবহার করে একটি মেসেজিং পোর্ট তৈরি করা হয়, তখন Chrome একটি নেটিভ মেসেজিং হোস্ট প্রসেস চালু করে এবং পোর্টটি ধ্বংস না হওয়া পর্যন্ত সেটিকে চালু রাখে। অন্যদিকে, যখন কোনো মেসেজিং পোর্ট তৈরি না করে runtime.sendNativeMessage() ব্যবহার করে একটি মেসেজ পাঠানো হয়, তখন Chrome প্রতিটি মেসেজের জন্য একটি নতুন নেটিভ মেসেজিং হোস্ট প্রসেস চালু করে। সেক্ষেত্রে, হোস্ট প্রসেস দ্বারা তৈরি প্রথম মেসেজটিকে মূল অনুরোধের প্রতিক্রিয়া হিসাবে গণ্য করা হয় এবং runtime.sendNativeMessage() কল করার সময় নির্দিষ্ট করা রেসপন্স কলব্যাকে Chrome সেটিকে পাঠিয়ে দেয়। এক্ষেত্রে নেটিভ মেসেজিং হোস্ট দ্বারা তৈরি অন্য সব মেসেজ উপেক্ষা করা হয়।

একটি নেটিভ অ্যাপ্লিকেশনের সাথে সংযোগ স্থাপন করা হচ্ছে

একটি নেটিভ অ্যাপ্লিকেশন থেকে এবং তাতে বার্তা পাঠানো ও গ্রহণ করা ক্রস-এক্সটেনশন মেসেজিংয়ের মতোই। মূল পার্থক্য হলো, runtime.connectNative() এর পরিবর্তে runtime.connect() এবং runtime.sendNativeMessage() এর পরিবর্তে runtime.sendMessage() ব্যবহৃত হয়।

এই পদ্ধতিগুলো ব্যবহার করার জন্য, আপনার এক্সটেনশনের ম্যানিফেস্ট ফাইলে 'nativeMessaging' পারমিশনটি অবশ্যই ঘোষণা করতে হবে।

এই মেথডগুলো কন্টেন্ট স্ক্রিপ্টের ভিতরে পাওয়া যায় না, শুধুমাত্র আপনার এক্সটেনশনের পেজ এবং সার্ভিস ওয়ার্কারের ভিতরেই পাওয়া যায়। কন্টেন্ট স্ক্রিপ্ট থেকে নেটিভ অ্যাপ্লিকেশনে যোগাযোগ করার জন্য, মেসেজটি আপনার সার্ভিস ওয়ার্কারে পাঠান, যাতে এটি নেটিভ অ্যাপ্লিকেশনে পৌঁছে যায়।

নিম্নলিখিত উদাহরণটি একটি runtime.Port অবজেক্ট তৈরি করে যা নেটিভ মেসেজিং হোস্ট com.my_company.my_application এর সাথে সংযুক্ত থাকে, সেই পোর্ট থেকে মেসেজের জন্য শোনা শুরু করে এবং একটি বহির্গামী মেসেজ পাঠায়:

const port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener((msg) => {
  console.log('Received', msg);
});
port.onDisconnect.addListener(() => {
  if (chrome.runtime.lastError) {
    console.error(
      'Disconnected due to error:',
      chrome.runtime.lastError.message
    );
  } else {
    console.log('Disconnected');
  }
});
port.postMessage({text: 'Hello, my_application'});

পোর্ট তৈরি না করেই নেটিভ অ্যাপ্লিকেশনে বার্তা পাঠাতে runtime.sendNativeMessage ব্যবহার করুন, যেমন:

chrome.runtime.sendNativeMessage(
  'com.my_company.my_application',
  {text: 'Hello'},
  (response) => {
    if (chrome.runtime.lastError) {
      console.error(
        'Error sending native message:',
        chrome.runtime.lastError.message
      );
      return;
    }
    console.log('Received', response);
  }
);

নেটিভ মেসেজিং ডিবাগ করুন

যখন নেটিভ মেসেজিং-এ ব্যর্থতা ঘটে, তখন ডায়াগনস্টিক আউটপুট ক্রোমের এরর লগে লেখা হয়।

লিনাক্স এবং ম্যাকওএস

# Linux
google-chrome --enable-logging=stderr --log-level=1 2>&1 | \
  grep -E "native_messag|launch_context"

# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --enable-logging=stderr --log-level=1 2>&1 | \
  grep -E "native_messag|launch_context"

উইন্ডোজ

লগিং সক্রিয় করে ক্রোম চালু করুন:

chrome.exe --enable-logging --log-level=1

বিদ্যমান কোনো ক্রোম প্রসেসের সাথে সংযুক্ত না হয়ে একটি পৃথক ইনস্ট্যান্স চালু করতে --user-data-dir="%TEMP%\nm-debug" পাস করুন।

আউটপুট দেখতে, PowerShell ব্যবহার করে chrome_debug.log স্ট্রিম করুন:

$log = "$env:LOCALAPPDATA\Google\Chrome\User Data\chrome_debug.log"
Get-Content -Wait $log | Select-String "native_messag|launch_context"

এছাড়াও আপনি একটি টেক্সট এডিটরে chrome_debug.log ফাইলটি খুলে launch_context.cc অথবা native_message_process_host.cc খুঁজে দেখতে পারেন।

মূল লগিং বিবরণ

  • launch_context.cc তে ম্যানিফেস্ট লুকআপ এবং পার্সিং-এর ব্যর্থতাগুলো ওয়ার্নিং হিসেবে লগ করা হয়। --log-level= 2 (ERROR)-এর পরিবর্তে --log-level=1 ব্যবহার করুন, যা এই স্টার্টআপ ডায়াগনস্টিকসগুলোকে দমন করে।
  • ম্যানিফেস্ট এবং বাইনারি লঞ্চের ত্রুটি খুঁজে পেতে launch_context এবং পেলোড সাইজ ও পাইপ কমিউনিকেশনের ত্রুটি খুঁজে পেতে native_messag অনুসন্ধান করুন।

সাধারণ ভুল

এখানে কিছু সাধারণ ভুল এবং সেগুলো সমাধানের উপায় দেওয়া হলো:

নেটিভ মেসেজিং হোস্ট চালু করতে ব্যর্থ হয়েছে।

নেটিভ মেসেজিং হোস্ট ফাইলটি চালানোর জন্য আপনার পর্যাপ্ত অনুমতি আছে কিনা তা যাচাই করুন।

নির্দিষ্ট করা নেটিভ মেসেজিং হোস্ট নামটি অবৈধ।

নামটিতে কোনো অবৈধ অক্ষর আছে কিনা তা পরীক্ষা করুন। শুধুমাত্র ছোট হাতের অক্ষর, সংখ্যা, আন্ডারস্কোর এবং ডট অনুমোদিত। কোনো নাম ডট দিয়ে শুরু বা শেষ হতে পারবে না এবং একটি ডটের পরে আরেকটি ডট থাকতে পারবে না।

নেটিভ হোস্ট প্রস্থান করেছে।

ক্রোম বার্তাটি পড়ার আগেই নেটিভ মেসেজিং হোস্টের সাথে সংযোগ বিচ্ছিন্ন হয়ে গিয়েছিল। এটি সম্ভবত আপনার নেটিভ মেসেজিং হোস্ট থেকেই শুরু হয়েছে।

নির্দিষ্ট নেটিভ মেসেজিং হোস্ট খুঁজে পাওয়া যায়নি।

নিম্নলিখিতগুলি যাচাই করুন:

  • এক্সটেনশন এবং ম্যানিফেস্ট ফাইলে নামটি কি সঠিকভাবে লেখা হয়েছে?
  • উইন্ডোজে, রেজিস্ট্রি কী-টি কি HKEY_CURRENT_USER অথবা HKEY_LOCAL_MACHINE অধীনে বিদ্যমান, এবং এর ডিফল্ট ভ্যালুটি কি সম্পূর্ণ ম্যানিফেস্ট পাথকে নির্দেশ করে? ক্রোম প্রথমে ৩২-বিট রেজিস্ট্রি ভিউ, তারপর ৬৪-বিট ভিউ কোয়েরি করে। কী-টি যাচাই করতে regedit ব্যবহার করুন। নেটিভ মেসেজিং হোস্টের অবস্থান দেখুন।
  • macOS এবং Linux-এ, ম্যানিফেস্ট ফাইলটি কি প্রত্যাশিত ডিরেক্টরিতে অবস্থিত এবং হোস্টের নামে নামকরণ করা হয়েছে (যেমন com.my_company.my_application.json )? নেটিভ মেসেজিং হোস্টের অবস্থান দেখুন।
  • ম্যানিফেস্ট ফাইলটি কি সঠিক ফরম্যাটে আছে? বিশেষ করে, JSON-টি কি বৈধ ও সুগঠিত এবং এর মানগুলো কি একটি নেটিভ মেসেজিং হোস্ট ম্যানিফেস্টের সংজ্ঞার সাথে মেলে?
  • path উল্লেখিত ফাইলটি কি বিদ্যমান? উইন্ডোজে পাথ রিলেটিভ হতে পারে, কিন্তু ম্যাকওএস এবং লিনাক্সে পাথ অবশ্যই অ্যাবসোলিউট হতে হবে।

নির্দিষ্ট নেটিভ মেসেজিং হোস্টে প্রবেশ নিষিদ্ধ।

এক্সটেনশনটির অরিজিন কি allowed_origins এ তালিকাভুক্ত আছে?

নেটিভ মেসেজিং হোস্টের সাথে যোগাযোগের সময় ত্রুটি।

এটি নেটিভ মেসেজিং হোস্টে কমিউনিকেশন প্রোটোকলের ভুল বাস্তবায়ন নির্দেশ করে।

  • নিশ্চিত করুন যে stdout এর সমস্ত আউটপুট নেটিভ মেসেজিং প্রোটোকল মেনে চলে। যদি আপনি ডিবাগিংয়ের উদ্দেশ্যে কিছু ডেটা প্রিন্ট করতে চান, তাহলে stderr এ লিখুন।
  • নিশ্চিত করুন যে ৩২-বিট মেসেজের দৈর্ঘ্যটি প্ল্যাটফর্মের নিজস্ব পূর্ণসংখ্যা ফরম্যাটে (লিটল-এন্ডিয়ান / বিগ-এন্ডিয়ান) রয়েছে।
  • বার্তার দৈর্ঘ্য 1024*1024 এর বেশি হবে না।
  • বার্তার আকার অবশ্যই বার্তার বাইট সংখ্যার সমান হতে হবে। এটি একটি স্ট্রিং-এর 'দৈর্ঘ্য' থেকে ভিন্ন হতে পারে, কারণ অক্ষরগুলো একাধিক বাইট দ্বারা উপস্থাপিত হতে পারে।
  • শুধুমাত্র উইন্ডোজের জন্য: নিশ্চিত করুন যে প্রোগ্রামটির I/O মোড O_BINARY তে সেট করা আছে। ডিফল্টরূপে, I/O মোড O_TEXT থাকে, যা মেসেজ ফরম্যাটকে নষ্ট করে দেয়, কারণ লাইন ব্রেক ( \n = 0A ) উইন্ডোজ-স্টাইলের লাইন এন্ডিং ( \r\n = 0D 0A ) দ্বারা প্রতিস্থাপিত হয়। __setmode ব্যবহার করে I/O মোড সেট করা যায়।