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

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