नेटिव मैसेज की सुविधा

एक्सटेंशन, नेटिव ऐप्लिकेशन के साथ मैसेज शेयर कर सकते हैं. इसके लिए, वे ऐसे एपीआई का इस्तेमाल करते हैं जो अन्य मैसेज पास करने वाले एपीआई की तरह काम करता है. इस सुविधा के साथ काम करने वाले नेटिव ऐप्लिकेशन को नेटिव मैसेजिंग होस्ट रजिस्टर करना होगा. इससे एक्सटेंशन के साथ कम्यूनिकेट किया जा सकेगा. 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 और macOS पर, पाथ पूरा होना चाहिए. Windows पर, यह मेनिफ़ेस्ट फ़ाइल वाले डायरेक्ट्री के हिसाब से हो सकता है. होस्ट प्रोसेस, उस डायरेक्ट्री पर सेट की गई मौजूदा डायरेक्ट्री से शुरू होती है जिसमें होस्ट बाइनरी होती है. उदाहरण के लिए, अगर इस पैरामीटर को C:\Application\nm_host.exe पर सेट किया जाता है, तो यह मौजूदा डायरेक्ट्री `C:\Application` से शुरू होगा.
type
नेटिव मैसेजिंग होस्ट से कम्यूनिकेट करने के लिए इस्तेमाल किए गए इंटरफ़ेस का टाइप. इस पैरामीटर की सिर्फ़ एक वैल्यू हो सकती है: stdio. इससे पता चलता है कि Chrome को होस्ट से कम्यूनिकेट करने के लिए, stdin और stdout का इस्तेमाल करना चाहिए.
allowed_origins
उन एक्सटेंशन की सूची जिन्हें नेटिव मैसेजिंग होस्ट का ऐक्सेस होना चाहिए. allowed_origins की वैल्यू में वाइल्डकार्ड शामिल नहीं किए जा सकते.

नेटिव मैसेजिंग होस्ट की जगह

मेनिफ़ेस्ट फ़ाइल की जगह, प्लैटफ़ॉर्म के हिसाब से तय होती है.

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-बिट रजिस्ट्री से क्वेरी की जाती है.

macOS और Linux पर, नेटिव मैसेजिंग होस्ट की मेनिफ़ेस्ट फ़ाइल की जगह ब्राउज़र (Google Chrome, Google Chrome for Testing या Chromium) के हिसाब से अलग-अलग होती है. सिस्टम-वाइड नेटिव मैसेजिंग होस्ट को एक तय जगह पर खोजा जाता है. वहीं, उपयोगकर्ता-लेवल के नेटिव मैसेजिंग होस्ट को उपयोगकर्ता प्रोफ़ाइल डायरेक्ट्री के NativeMessagingHosts/ सबडायरेक्ट्री में खोजा जाता है.

macOS (पूरे सिस्टम में)
Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json
Google Chrome for Testing: /Library/Google/ChromeForTesting/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
Google Chrome for Testing: ~/Library/Application Support/Google/ChromeForTesting/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
Google Chrome for Testing: /etc/opt/chrome_for_testing/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
Google Chrome for Testing: ~/.config/google-chrome-for-testing/NativeMessagingHosts/com.my_company.my_application.json
Chromium: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

नेटिव मैसेजिंग प्रोटोकॉल

Chrome, हर नेटिव मैसेजिंग होस्ट को अलग प्रोसेस में शुरू करता है. साथ ही, स्टैंडर्ड इनपुट (stdin) और स्टैंडर्ड आउटपुट (stdout) का इस्तेमाल करके उससे कम्यूनिकेट करता है. दोनों दिशाओं में मैसेज भेजने के लिए, एक ही फ़ॉर्मैट का इस्तेमाल किया जाता है. हर मैसेज को JSON का इस्तेमाल करके क्रम से लगाया जाता है. साथ ही, UTF-8 में कोड में बदला जाता है. इसके अलावा, हर मैसेज से पहले नेटिव बाइट ऑर्डर में 32-बिट मैसेज की लंबाई होती है. नेटिव मैसेजिंग होस्ट से भेजे जाने वाले किसी मैसेज का ज़्यादा से ज़्यादा साइज़ 1 एमबी हो सकता है. ऐसा इसलिए किया जाता है, ताकि Chrome को नेटिव ऐप्लिकेशन के गलत इस्तेमाल से बचाया जा सके. नेटिव मैसेजिंग होस्ट को भेजे गए मैसेज का साइज़ 64 MiB से ज़्यादा नहीं होना चाहिए.

नेटिव मैसेजिंग होस्ट का पहला आर्ग्युमेंट, कॉलर का ऑरिजिन होता है. आम तौर पर, यह chrome-extension://[ID of allowed extension] होता है. इससे नेटिव मैसेजिंग होस्ट, मैसेज के सोर्स की पहचान कर पाते हैं. ऐसा तब होता है, जब नेटिव मैसेजिंग होस्ट मेनिफ़ेस्ट में allowed_origins कुंजी में एक से ज़्यादा एक्सटेंशन तय किए गए हों.

Windows पर, नेटिव मैसेजिंग होस्ट को कॉल करने वाली Chrome नेटिव विंडो के हैंडल के साथ-साथ, कमांड लाइन आर्ग्युमेंट भी पास किया जाता है: --parent-window=<decimal handle value>. इससे नेटिव मैसेजिंग होस्ट, सही तरीके से पैरंट की गई नेटिव यूज़र इंटरफ़ेस विंडो बना पाता है. ध्यान दें कि अगर कॉलिंग कॉन्टेक्स्ट कोई सर्विस वर्कर है, तो यह वैल्यू 0 होगी.

runtime.connectNative() का इस्तेमाल करके मैसेजिंग पोर्ट बनाए जाने पर, Chrome एक नेटिव मैसेजिंग होस्ट प्रोसेस शुरू करता है. यह प्रोसेस तब तक चलती रहती है, जब तक पोर्ट बंद नहीं हो जाता. दूसरी ओर, जब मैसेजिंग पोर्ट बनाए बिना runtime.sendNativeMessage() का इस्तेमाल करके कोई मैसेज भेजा जाता है, तो Chrome हर मैसेज के लिए एक नई नेटिव मैसेजिंग होस्ट प्रोसेस शुरू करता है. ऐसे में, होस्ट प्रोसेस से जनरेट हुए पहले मैसेज को ओरिजनल अनुरोध के जवाब के तौर पर हैंडल किया जाता है. साथ ही, Chrome इसे runtime.sendNativeMessage() को कॉल करते समय बताए गए रिस्पॉन्स कॉलबैक को पास करेगा. ऐसे में, नेटिव मैसेजिंग होस्ट से जनरेट किए गए अन्य सभी मैसेज को अनदेखा कर दिया जाता है.

किसी नेटिव ऐप्लिकेशन से कनेक्ट करना

किसी नेटिव ऐप्लिकेशन को मैसेज भेजने और उससे मैसेज पाने की प्रोसेस, क्रॉस-एक्सटेंशन मैसेजिंग से काफ़ी मिलती-जुलती है. इनमें मुख्य अंतर यह है कि runtime.connect() की जगह runtime.connectNative() और runtime.sendMessage() की जगह runtime.sendNativeMessage() का इस्तेमाल किया जाता है.

इन तरीकों का इस्तेमाल करने के लिए, आपके एक्सटेंशन की मेनिफ़ेस्ट फ़ाइल में "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);
  }
);

नेटिव मैसेजिंग को डीबग करना

नेटिव मैसेजिंग की सुविधा काम न करने पर, डाइग्नोस्टिक आउटपुट को Chrome के गड़बड़ी लॉग में लिखा जाता है.

Linux और macOS

# 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"

Windows

लॉगिंग की सुविधा चालू करके Chrome लॉन्च करें:

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

--user-data-dir="%TEMP%\nm-debug" को पास करके, Chrome की मौजूदा प्रोसेस से अटैच किए बिना एक अलग इंस्टेंस लॉन्च करें.

आउटपुट देखने के लिए, 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 में मेनिफ़ेस्ट लुकअप और पार्स करने से जुड़ी गड़बड़ियों को चेतावनियों के तौर पर लॉग किया जाता है. 2 (ERROR) के बजाय --log-level=1 का इस्तेमाल करें. इससे स्टार्टअप डाइग्नोस्टिक्स बंद हो जाते हैं.
  • मैनिफ़ेस्ट और बाइनरी लॉन्च करने से जुड़ी गड़बड़ियों को ढूंढने के लिए, launch_context खोजें. साथ ही, पेलोड के साइज़ और पाइप कम्यूनिकेशन से जुड़ी गड़बड़ियों को ढूंढने के लिए, native_messag खोजें.

आम तौर पर होने वाली गड़बड़ियां

यहां कुछ आम गड़बड़ियां और उन्हें ठीक करने के तरीके दिए गए हैं:

नेटिव मैसेजिंग होस्ट शुरू नहीं की जा सकी.

देखें कि आपके पास नेटिव मैसेजिंग होस्ट फ़ाइल को चलाने की ज़रूरी अनुमतियां हैं या नहीं.

नेटिव मैसेजिंग होस्ट का अमान्य नाम दिया गया है.

देखें कि नाम में अमान्य वर्ण तो नहीं हैं. सिर्फ़ अंग्रेज़ी के छोटे अक्षर, अंक, अंडरस्कोर, और बिंदु इस्तेमाल किए जा सकते हैं. नाम की शुरुआत या आखिर में डॉट नहीं हो सकता. साथ ही, एक डॉट के बाद दूसरा डॉट नहीं हो सकता.

नेटिव होस्ट बंद हो गया है.

Chrome के मैसेज पढ़ने से पहले ही, नेटिव मैसेजिंग होस्ट का पाइप टूट गया था. ऐसा हो सकता है कि यह अनुरोध, नेटिव मैसेजिंग होस्ट से शुरू किया गया हो.

बताया गया नेटिव मैसेजिंग होस्ट नहीं मिला.

इनकी जांच करें:

  • क्या एक्सटेंशन और मेनिफ़ेस्ट फ़ाइल में नाम की स्पेलिंग सही है?
  • क्या Windows पर, रजिस्ट्री की यह कुंजी HKEY_CURRENT_USER या HKEY_LOCAL_MACHINE में मौजूद है? साथ ही, क्या इसकी डिफ़ॉल्ट वैल्यू, पूरे मेनिफ़ेस्ट पाथ की ओर इशारा करती है? Chrome, सबसे पहले 32-बिट रजिस्ट्री व्यू और फिर 64-बिट व्यू के लिए क्वेरी करता है. कुंजी की पुष्टि करने के लिए, regedit का इस्तेमाल करें. नेटिव मैसेजिंग होस्ट की जगह की जानकारी देखें.
  • क्या macOS और Linux पर, मेनिफ़ेस्ट फ़ाइल सही डायरेक्ट्री में मौजूद है और उसका नाम होस्ट के नाम पर रखा गया है. जैसे, com.my_company.my_application.json? नेटिव मैसेजिंग होस्ट की जगह देखें.
  • क्या मेनिफ़ेस्ट फ़ाइल सही फ़ॉर्मैट में है? खास तौर पर, क्या JSON मान्य है और सही फ़ॉर्मैट में है? साथ ही, क्या वैल्यू नेटिव मैसेजिंग होस्ट मेनिफ़ेस्ट की परिभाषा से मेल खाती हैं?
  • क्या path में बताई गई फ़ाइल मौजूद है? Windows पर, पाथ रिलेटिव हो सकते हैं. हालांकि, macOS और Linux पर पाथ पूरे होने चाहिए.

नेटिव मैसेजिंग होस्ट को ऐक्सेस करने की अनुमति नहीं है.

क्या एक्सटेंशन का ऑरिजिन, allowed_origins में शामिल है?

नेटिव मैसेजिंग होस्ट से कनेक्ट करने में गड़बड़ी हुई.

इससे पता चलता है कि नेटिव मैसेजिंग होस्ट में कम्यूनिकेशन प्रोटोकॉल को गलत तरीके से लागू किया गया है.

  • पक्का करें कि stdout में मौजूद सभी आउटपुट, नेटिव मैसेजिंग प्रोटोकॉल के मुताबिक हों. अगर आपको डीबग करने के लिए कुछ डेटा प्रिंट करना है, तो stderr को लिखें.
  • पक्का करें कि 32-बिट मैसेज की लंबाई, प्लैटफ़ॉर्म के नेटिव पूर्णांक फ़ॉर्मैट (लिटिल-एंडियन / बिग-एंडियन) में हो.
  • मैसेज की लंबाई 1024*1024 से ज़्यादा नहीं होनी चाहिए.
  • मैसेज का साइज़, मैसेज में मौजूद बाइट की संख्या के बराबर होना चाहिए. यह किसी स्ट्रिंग की "लंबाई" से अलग हो सकता है, क्योंकि वर्णों को कई बाइट से दिखाया जा सकता है.
  • सिर्फ़ Windows के लिए: पक्का करें कि प्रोग्राम का I/O मोड O_BINARY पर सेट हो. डिफ़ॉल्ट रूप से, I/O मोड O_TEXT होता है. इससे मैसेज का फ़ॉर्मैट खराब हो जाता है, क्योंकि लाइन ब्रेक (\n = 0A) को Windows-स्टाइल लाइन एंडिंग (\r\n = 0D 0A) से बदल दिया जाता है. I/O मोड को __setmode का इस्तेमाल करके सेट किया जा सकता है.