ส่วนขยายสามารถแลกเปลี่ยนข้อความกับแอปพลิเคชันเนทีฟได้โดยใช้ 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