การรับส่งข้อความแบบเดิม

ส่วนขยายสามารถแลกเปลี่ยนข้อความกับแอปพลิเคชันเนทีฟได้โดยใช้ API ที่คล้ายกับ API การส่งข้อความอื่นๆ แอปพลิเคชันเนทีฟที่รองรับฟีเจอร์นี้ต้องลงทะเบียนโฮสต์การรับส่งข้อความดั้งเดิมที่สื่อสารกับส่วนขยายได้ 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/"]
}

ไฟล์ Manifest ของโฮสต์การรับส่งข้อความในเครื่องต้องเป็น JSON ที่ถูกต้องและมีฟิลด์ต่อไปนี้

name
ชื่อของโฮสต์การรับส่งข้อความในเครื่อง ไคลเอ็นต์ส่งสตริงนี้ไปยัง runtime.connectNative() หรือ runtime.sendNativeMessage() ชื่อนี้ต้องประกอบด้วยอักขระที่เป็นตัวอักษรพิมพ์เล็กและตัวเลขคละกัน ขีดล่าง และจุดเท่านั้น ชื่อต้องไม่ขึ้นต้นหรือลงท้ายด้วยจุด และจุดต้องไม่ตามด้วยจุดอีกจุด
description
คำอธิบายแอปพลิเคชันแบบย่อ
path
เส้นทางไปยังไบนารีของโฮสต์การรับส่งข้อความในเครื่อง เส้นทางใน Linux และ macOS ต้องเป็นเส้นทางสัมบูรณ์ ใน Windows เส้นทางอาจเป็นแบบสัมพัทธ์กับไดเรกทอรีที่มีไฟล์ Manifest ระบบจะเริ่มกระบวนการของโฮสต์โดยตั้งค่าไดเรกทอรีปัจจุบันเป็นไดเรกทอรีที่มีไบนารีของโฮสต์ เช่น หากตั้งค่าพารามิเตอร์นี้เป็น C:\Application\nm_host.exe ก็จะเริ่มต้นด้วยไดเรกทอรีปัจจุบัน "C:\Application"
type
ประเภทอินเทอร์เฟซที่ใช้สื่อสารกับโฮสต์การรับส่งข้อความแบบดั้งเดิม พารามิเตอร์นี้มีค่าที่เป็นไปได้ 1 ค่าคือ stdio ซึ่งหมายความว่า Chrome ควรใช้ stdin และ stdout เพื่อสื่อสารกับโฮสต์
allowed_origins
รายการส่วนขยายที่ควรมีสิทธิ์เข้าถึงโฮสต์การรับส่งข้อความที่มาพร้อมระบบ ค่า allowed-origins ต้องไม่มีไวลด์การ์ด

ตำแหน่งของโฮสต์การรับส่งข้อความในเครื่อง

ตำแหน่งของไฟล์ Manifest จะขึ้นอยู่กับแพลตฟอร์ม

ใน Windows ไฟล์ Manifest จะอยู่ที่ใดก็ได้ในระบบไฟล์ โปรแกรมติดตั้งแอปพลิเคชันต้องสร้างคีย์รีจิสทรี HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application หรือ HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application และตั้งค่าเริ่มต้นของคีย์ดังกล่าวให้เป็นเส้นทางแบบเต็มไปยังไฟล์ Manifest เช่น ใช้คำสั่งต่อไปนี้

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 ตำแหน่งของไฟล์ Manifest ของโฮสต์การรับส่งข้อความแบบเนทีฟจะแตกต่างกันไปตามเบราว์เซอร์ (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
Linux (ทั้งระบบ)
Google Chrome: /etc/opt/chrome/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
Chromium: ~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json

โปรโตคอลการรับส่งข้อความดั้งเดิม

Chrome จะเริ่มต้นโฮสต์การรับส่งข้อความดั้งเดิมแต่ละรายการในกระบวนการที่แยกจากกัน และสื่อสารกับโฮสต์โดยใช้อินพุตมาตรฐาน (stdin) และเอาต์พุตมาตรฐาน (stdout) ใช้รูปแบบเดียวกันในการส่งข้อความทั้ง 2 ทิศทาง โดยแต่ละข้อความจะเรียงลำดับโดยใช้ JSON ที่เข้ารหัส UTF-8 และนำหน้าด้วยความยาวข้อความ 32 บิตตามลำดับไบต์ดั้งเดิม ขนาดสูงสุดของข้อความเดียวจากโฮสต์การรับส่งข้อความแบบเนทีฟคือ 1 MB โดยหลักๆ แล้วเพื่อปกป้อง Chrome จากแอปพลิเคชันเนทีฟที่ทำงานผิดปกติ ข้อความที่ส่งไปยังโฮสต์การรับส่งข้อความในตัวมีขนาดได้สูงสุด 4 GB

อาร์กิวเมนต์แรกสำหรับโฮสต์การรับส่งข้อความแบบดั้งเดิมคือต้นทางของผู้เรียก ซึ่งโดยปกติแล้วจะเป็น chrome-extension://[ID of allowed extension] วิธีนี้จะช่วยให้โฮสต์การรับส่งข้อความดั้งเดิมระบุแหล่งที่มาของข้อความได้เมื่อมีการระบุส่วนขยายหลายรายการในคีย์ allowed_origins ในไฟล์ Manifest ของโฮสต์การรับส่งข้อความเนทีฟ

ใน Windows ระบบจะส่งอาร์กิวเมนต์บรรทัดคำสั่งที่มีแฮนเดิลไปยังหน้าต่าง Chrome ดั้งเดิมที่เรียกใช้ --parent-window=<decimal handle value> ไปยังโฮสต์การรับส่งข้อความในเครื่องด้วย ซึ่งจะช่วยให้โฮสต์การรับส่งข้อความในเครื่องสร้างหน้าต่าง UI ของอุปกรณ์ที่เชื่อมโยงกับหน้าต่างหลักได้อย่างถูกต้อง โปรดทราบว่าค่านี้จะมีค่าเป็น 0 หากบริบทการเรียกใช้คือ Service Worker

เมื่อสร้างพอร์ตการรับส่งข้อความโดยใช้ runtime.connectNative() Chrome จะเริ่มกระบวนการโฮสต์การรับส่งข้อความแบบเนทีฟและทำให้ทำงานต่อไปจนกว่าพอร์ตจะถูกทำลาย ในทางกลับกัน เมื่อส่งข้อความโดยใช้ runtime.sendNativeMessage() โดยไม่สร้างพอร์ตการรับส่งข้อความ Chrome จะเริ่มกระบวนการโฮสต์การรับส่งข้อความแบบเนทีฟใหม่สำหรับแต่ละข้อความ ในกรณีนี้ ระบบจะจัดการข้อความแรกที่สร้างโดยกระบวนการของโฮสต์เป็นการตอบกลับคำขอเดิม และ Chrome จะส่งข้อความนั้นไปยังการเรียกกลับคำตอบที่ระบุเมื่อเรียก runtime.sendNativeMessage() ระบบจะไม่สนใจข้อความอื่นๆ ทั้งหมดที่โฮสต์การรับส่งข้อความดั้งเดิมสร้างขึ้นในกรณีดังกล่าว

การเชื่อมต่อกับแอปพลิเคชันเริ่มต้น

การส่งและการรับข้อความจากแอปพลิเคชันเนทีฟนั้นคล้ายกับการรับส่งข้อความข้ามส่วนขยาย ความแตกต่างหลักๆ คือจะใช้ runtime.connectNative() แทน runtime.connect() และจะใช้ runtime.sendNativeMessage() แทน runtime.sendMessage()

หากต้องการใช้วิธีการเหล่านี้ คุณต้องประกาศสิทธิ์ "nativeMessaging" ในไฟล์ Manifest ของส่วนขยาย

วิธีการเหล่านี้จะใช้ไม่ได้ภายในสคริปต์เนื้อหา แต่จะใช้ได้เฉพาะในหน้าเว็บและ Service Worker ของส่วนขยายเท่านั้น หากต้องการสื่อสารจากสคริปต์เนื้อหาไปยังแอปพลิเคชันเนทีฟ ให้ส่งข้อความไปยัง Service Worker เพื่อส่งต่อไปยังแอปพลิเคชันเนทีฟ

ตัวอย่างต่อไปนี้จะสร้างออบเจ็กต์ runtime.Port ที่เชื่อมต่อกับโฮสต์การรับส่งข้อความดั้งเดิม com.my_company.my_application เริ่มฟังข้อความจากพอร์ตนั้นแล้วส่งข้อความขาออก 1 ข้อความ

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 หรือละเมิดโปรโตคอลการสื่อสาร ใน Linux และ macOS คุณจะเข้าถึงบันทึกนี้ได้โดยการเริ่ม Chrome จากบรรทัดคำสั่งและดูเอาต์พุตในเทอร์มินัล ใน Windows ให้ใช้ --enable-logging ตามที่อธิบายไว้ในวิธีเปิดใช้การบันทึก

ข้อผิดพลาดที่พบบ่อยและเคล็ดลับในการแก้ปัญหามีดังนี้

เริ่มโฮสต์การรับส่งข้อความแบบดั้งเดิมไม่สำเร็จ

ตรวจสอบว่าคุณมีสิทธิ์เพียงพอที่จะเรียกใช้ไฟล์โฮสต์การรับส่งข้อความที่มาพร้อมระบบหรือไม่

ระบุชื่อโฮสต์การรับส่งข้อความดั้งเดิมไม่ถูกต้อง

ตรวจสอบว่าชื่อมีอักขระที่ไม่ถูกต้องหรือไม่ อนุญาตให้ใช้เฉพาะอักขระที่เป็นตัวอักษรพิมพ์เล็กและตัวเลขคละกัน ขีดล่าง และจุด ชื่อต้องไม่ขึ้นต้นหรือลงท้ายด้วยจุด และจุดต้องไม่ตามด้วยจุดอีกจุด

ออกจากโฮสต์เนทีฟแล้ว

ไปป์ไปยังโฮสต์การรับส่งข้อความแบบเนทีฟใช้งานไม่ได้ก่อนที่ Chrome จะอ่านข้อความ ซึ่งมักเริ่มต้นจากโฮสต์การรับส่งข้อความในเครื่อง

ไม่พบโฮสต์การรับส่งข้อความที่มาพร้อมระบบที่ระบุ

โปรดตรวจสอบสิ่งต่อไปนี้

  • ชื่อในส่วนขยายและไฟล์ Manifest สะกดถูกต้องไหม
  • ไฟล์ Manifest อยู่ในไดเรกทอรีที่ถูกต้องและมีชื่อที่ถูกต้องหรือไม่ โปรดดูรูปแบบที่คาดไว้ในตำแหน่งโฮสต์การรับส่งข้อความดั้งเดิม
  • ไฟล์ Manifest มีรูปแบบที่ถูกต้องไหม โดยเฉพาะอย่างยิ่ง โปรดตรวจสอบว่า JSON ถูกต้องและอยู่ในรูปแบบที่ถูกต้อง รวมถึงค่าต่างๆ ตรงกับคำจำกัดความของไฟล์ Manifest ของโฮสต์การรับส่งข้อความแบบเนทีฟหรือไม่
  • ไฟล์ที่ระบุใน path มีอยู่ไหม เส้นทางใน Windows อาจสัมพันธ์กัน แต่ใน macOS และ Linux เส้นทางต้องเป็นแบบสัมบูรณ์

ชื่อโฮสต์ของโฮสต์การรับส่งข้อความที่มาพร้อมระบบไม่ได้จดทะเบียน (Windows เท่านั้น)

ไม่พบโฮสต์การรับส่งข้อความในเครื่องในรีจิสทรีของ Windows ตรวจสอบอีกครั้งโดยใช้ regedit ว่าระบบสร้างคีย์จริงๆ และตรงกับรูปแบบที่กำหนดตามที่ระบุไว้ในตำแหน่งโฮสต์การรับส่งข้อความแบบเนทีฟหรือไม่

ไม่อนุญาตให้เข้าถึงโฮสต์การรับส่งข้อความที่มาพร้อมระบบที่ระบุ

ต้นทางของส่วนขยายแสดงอยู่ใน allowed_origins ไหม

เกิดข้อผิดพลาดเมื่อสื่อสารกับโฮสต์การรับส่งข้อความเริ่มต้น

ซึ่งบ่งชี้ว่ามีการใช้โปรโตคอลการสื่อสารในโฮสต์การรับส่งข้อความที่มาพร้อมระบบไม่ถูกต้อง

  • ตรวจสอบว่าเอาต์พุตทั้งหมดใน stdout เป็นไปตามโปรโตคอลการรับส่งข้อความดั้งเดิม หากต้องการพิมพ์ข้อมูลบางส่วนเพื่อแก้ไขข้อบกพร่อง ให้เขียนไปที่ stderr
  • ตรวจสอบว่าความยาวข้อความ 32 บิตอยู่ในรูปแบบจำนวนเต็มของแพลตฟอร์ม (Little Endian/Big Endian)
  • ความยาวของข้อความต้องไม่เกิน 1024*1024
  • ขนาดข้อความต้องเท่ากับจำนวนไบต์ในข้อความ ซึ่งอาจแตกต่างจาก "ความยาว" ของสตริง เนื่องจากอักขระอาจแสดงด้วยไบต์หลายรายการ
  • Windows เท่านั้น: ตรวจสอบว่าโหมด I/O ของโปรแกรมตั้งค่าเป็น O_BINARY โดยค่าเริ่มต้น โหมด I/O คือ O_TEXT ซึ่งทำให้รูปแบบข้อความเสียหายเนื่องจากการขึ้นบรรทัดใหม่ (\n = 0A) จะแทนที่ด้วยส่วนท้ายบรรทัดแบบ Windows (\r\n = 0D 0A) โหมด I/O ตั้งค่าได้โดยใช้ __setmode