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

ส่วนขยายจะแลกเปลี่ยนข้อความกับแอปพลิเคชันที่มาพร้อมเครื่องโดยใช้ 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()

หากต้องการใช้เมธอดเหล่านี้ คุณต้องประกาศสิทธิ์ "การรับส่งข้อความเนทีฟ" ในไฟล์ 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 บิตอยู่ในรูปแบบเลขจำนวนเต็มดั้งเดิมของแพลตฟอร์ม (ตัวเล็ก / ใหญ่)
  • ข้อความต้องไม่เกิน 1024*1024
  • โดยขนาดข้อความจะต้องเท่ากับจำนวนไบต์ในข้อความ ซึ่งอาจแตกต่างจาก "length" ของสตริง เนื่องจากอักขระอาจแสดงเป็นหลายไบต์
  • Windows เท่านั้น: ตรวจสอบว่าตั้งค่าโหมด I/O ของโปรแกรมเป็น O_BINARY โดยค่าเริ่มต้น โหมด I/O คือ O_TEXT ซึ่งจะทำให้รูปแบบข้อความเสียหายเมื่อมีการขึ้นบรรทัดใหม่ (\n = 0A) จะถูกแทนที่ด้วยส่วนท้ายบรรทัดแบบ Windows (\r\n = 0D 0A) โหมด I/O ตั้งค่าได้โดยใช้ __setmode