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

ส่วนขยายและแอปสามารถแลกเปลี่ยนข้อความกับแอปพลิเคชันที่มาพร้อมเครื่องโดยใช้ API ที่คล้ายกับ API การส่งข้อความอื่นๆ แอปพลิเคชันที่มาพร้อมเครื่องซึ่งรองรับฟีเจอร์นี้จะต้องลงทะเบียน โฮสต์การรับส่งข้อความในเครื่องที่รู้วิธีสื่อสารกับส่วนขยาย Chrome จะเริ่มโฮสต์ใน กระบวนการที่แยกต่างหากและสื่อสารกับกระบวนการดังกล่าวโดยใช้สตรีมอินพุตมาตรฐานและเอาต์พุตมาตรฐาน

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

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

{
  "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 และ OSX เส้นทางต้องเป็นค่าสัมบูรณ์ ใน Windows อาจสัมพันธ์กับไดเรกทอรีที่มีไฟล์ Manifest อยู่ กระบวนการโฮสต์เริ่มต้นจากไดเรกทอรีปัจจุบันที่ตั้งค่าเป็นไดเรกทอรีที่มีไบนารีของโฮสต์ ตัวอย่างเช่น หากตั้งค่าพารามิเตอร์นี้เป็น C:\Application\nm_host.exe พารามิเตอร์นี้จะเริ่มต้นด้วยไดเรกทอรีปัจจุบัน C:\Application\
typeประเภทของอินเทอร์เฟซที่ใช้สื่อสารกับโฮสต์การรับส่งข้อความในเครื่อง ปัจจุบันมีเพียงค่าเดียวที่เป็นไปได้สำหรับพารามิเตอร์นี้: stdio ซึ่งเป็นการระบุว่า Chrome ควรใช้ stdin และ stdout ในการสื่อสารกับโฮสต์
allowed_originsรายการส่วนขยายที่ควรมีสิทธิ์เข้าถึงโฮสต์การรับส่งข้อความดั้งเดิม ไม่อนุญาตให้ใช้ไวลด์การ์ด เช่น chrome-extension://*/*

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

ตำแหน่งของไฟล์ 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 บิต รีจิสทรี

ใน OS X และ Linux ตำแหน่งไฟล์ Manifest ของโฮสต์การรับส่งข้อความดั้งเดิมจะแตกต่างกันไป (Google Chrome หรือ Chromium) โฮสต์การรับส่งข้อความดั้งเดิมของทั้งระบบได้รับการตรวจหา ขณะที่ค้นหาโฮสต์การรับส่งข้อความดั้งเดิมระดับผู้ใช้ในไดเรกทอรีย่อยภายใน ไดเรกทอรีโปรไฟล์ผู้ใช้ที่ชื่อ NativeMessagingHosts

  • OS X (ทั้งระบบ)
    • Google Chrome: /Library/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium: /Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
  • OS X (เส้นทางเริ่มต้นสำหรับผู้ใช้เฉพาะ)
    • 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 54 และเวอร์ชันก่อนหน้า ระบบจะส่งต้นทางเป็นพารามิเตอร์ที่ 2 แทนพารามิเตอร์แรก

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

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

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

การส่งหรือรับข้อความไปยังและจากแอปพลิเคชันของระบบนั้นคล้ายกับส่วนขยายข้ามระบบอย่างมาก การรับส่งข้อความ ความแตกต่างที่สำคัญคือจะมีการใช้ runtime.connectNative แทน ระบบใช้ runtime.connect และ runtime.sendNativeMessage แทน runtime.sendMessage. วิธีการเหล่านี้จะใช้ได้เฉพาะในกรณีที่ "การรับส่งข้อความที่มาพร้อมระบบ" มีการประกาศสิทธิ์ในแอป Manifest

ตัวอย่างต่อไปนี้จะสร้างออบเจ็กต์ 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);
  });

การแก้ไขข้อบกพร่องของการรับส่งข้อความในเครื่อง

เมื่อโฮสต์การรับส่งข้อความดั้งเดิมเริ่มต้นไม่ได้ จะเขียนไปยัง stderr หรือเมื่อมีการละเมิด โปรโตคอลการสื่อสาร ระบบจะเขียนเอาต์พุตลงในบันทึกข้อผิดพลาดของ Chrome ใน Linux และ OS X บันทึกนี้ สามารถเข้าถึงได้โดยง่ายด้วยการเปิด Chrome จากบรรทัดคำสั่งและดูเอาต์พุตใน เครื่องปลายทาง ใน Windows ให้ใช้ --enable-logging ตามที่อธิบายไว้ในวิธีเปิดใช้การบันทึก

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

  • เริ่มใช้โฮสต์การรับส่งข้อความในเครื่องไม่สำเร็จ
    • ตรวจสอบว่าคุณมีสิทธิ์เพียงพอที่จะเรียกใช้ไฟล์หรือไม่
  • ระบุชื่อโฮสต์การรับส่งข้อความดั้งเดิมไม่ถูกต้อง
    • ตรวจสอบว่าชื่อมีอักขระที่ไม่ถูกต้องหรือไม่ เฉพาะอักขระที่เป็นตัวอักษรพิมพ์เล็กและตัวเลขคละกัน โดยใช้ขีดล่างและจุดได้ ชื่อต้องไม่ขึ้นต้นหรือลงท้ายด้วยจุด และจุดไม่สามารถ ตามด้วยจุดอีกจุดหนึ่ง
  • ออกจากโฮสต์เนทีฟแล้ว
    • ไปป์ไปยังโฮสต์การรับส่งข้อความในเครื่องไม่ทำงานก่อนที่ Chrome จะอ่านข้อความ มากที่สุด ซึ่งน่าจะเริ่มต้นจากโฮสต์การรับส่งข้อความในเครื่องของคุณ
  • ไม่พบโฮสต์การรับส่งข้อความดั้งเดิมที่ระบุ
    • สะกดชื่อในส่วนขยายและในไฟล์ Manifest ถูกต้องไหม
    • ไฟล์ Manifest อยู่ในไดเรกทอรีที่ถูกต้องและมีชื่อที่ถูกต้องหรือไม่ ดูโฮสต์การรับส่งข้อความในเครื่อง ตำแหน่งสำหรับรูปแบบที่คาดไว้
    • ไฟล์ Manifest มีรูปแบบที่ถูกต้องไหม โดยเฉพาะอย่างยิ่ง ไวยากรณ์ JSON ถูกต้องหรือไม่และทำ ค่าตรงกับคำจำกัดความของไฟล์ Manifest ของโฮสต์การรับส่งข้อความเนทีฟหรือไม่
    • ไฟล์ที่ระบุใน path มีอยู่ไหม ใน Windows เส้นทางอาจสัมพันธ์กัน แต่ใน OS X และ Linux เส้นทางต้องเป็นค่าสัมบูรณ์
  • ชื่อโฮสต์ของโฮสต์การรับส่งข้อความในเครื่องไม่ได้ลงทะเบียน (เฉพาะ Windows)
  • ไม่อนุญาตให้เข้าถึงโฮสต์การรับส่งข้อความดั้งเดิมที่ระบุ
    • ต้นทางของส่วนขยายแสดงเป็นภาษา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