Các tiện ích và ứng dụng có thể trao đổi thông báo với các ứng dụng gốc bằng một API tương tự như các API truyền thông báo khác. Các ứng dụng gốc hỗ trợ tính năng này phải đăng ký máy chủ nhắn tin gốc biết cách giao tiếp với tiện ích. Chrome khởi động máy chủ trong một quy trình riêng và giao tiếp với máy chủ này bằng luồng đầu vào và luồng đầu ra tiêu chuẩn.
Máy chủ nhắn tin gốc
Để đăng ký máy chủ nhắn tin gốc, ứng dụng phải cài đặt một tệp kê khai xác định cấu hình máy chủ nhắn tin gốc. Dưới đây là một ví dụ về tệp kê khai:
{
"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/"
]
}
Tệp kê khai của máy chủ thông báo gốc phải là định dạng JSON hợp lệ và có chứa các trường sau:
Tên | Nội dung mô tả |
---|---|
name | Tên của máy chủ nhắn tin gốc. Ứng dụng sẽ chuyển chuỗi này đến runtime.connectNative hoặc runtime.sendNativeMessage. Tên này chỉ có thể chứa các ký tự chữ-số viết thường, dấu gạch dưới và dấu chấm. Tên không được bắt đầu hoặc kết thúc bằng một dấu chấm và theo sau không được là một dấu chấm khác. |
description | Nội dung mô tả ngắn về ứng dụng. |
path | Đường dẫn đến tệp nhị phân của máy chủ nhắn tin gốc. Trên Linux và OSX, đường dẫn phải là tuyệt đối. Trên Windows, giá trị này có thể tương đối với thư mục chứa tệp kê khai. Quá trình lưu trữ bắt đầu bằng việc đặt thư mục hiện tại thành thư mục chứa tệp nhị phân của máy chủ. Ví dụ: nếu tham số này được đặt thành C:\Application\nm_host.exe , thì tham số sẽ được bắt đầu bằng thư mục hiện tại C:\Application\ . |
type | Loại giao diện dùng để giao tiếp với máy chủ nhắn tin gốc. Hiện tại, bạn chỉ có thể sử dụng một giá trị cho tham số này: stdio . Nó cho biết rằng Chrome cần sử dụng stdin và stdout để giao tiếp với máy chủ. |
allowed_origins | Danh sách các tiện ích có quyền truy cập vào máy chủ nhắn tin gốc. Không cho phép các ký tự đại diện như chrome-extension://*/* . |
Vị trí máy chủ nhắn tin gốc
Vị trí của tệp kê khai phụ thuộc vào nền tảng.
Trên Windows, tệp kê khai có thể nằm ở bất cứ đâu trong hệ thống tệp. Trình cài đặt ứng dụng phải tạo khoá đăng ký HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_
hoặc HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\_com.my_company.my_application_
và đặt giá trị mặc định của khoá đó thành đường dẫn đầy đủ đến tệp kê khai. Ví dụ: sử dụng lệnh sau:
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f
hoặc sử dụng tệp .reg
sau:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application]
@="C:\\path\\to\\nmh-manifest.json"
Khi Chrome tìm kiếm các máy chủ nhắn tin gốc, trước tiên, hệ thống đăng ký 32 bit sẽ được truy vấn, sau đó là hệ thống đăng ký 64 bit.
Trên OS X và Linux, vị trí của tệp kê khai của máy chủ nhắn tin gốc sẽ khác nhau tuỳ theo trình duyệt (Google Chrome hoặc Chromium). Các máy chủ nhắn tin gốc trên toàn hệ thống được tra cứu tại một vị trí cố định, trong khi các máy chủ nhắn tin gốc cấp người dùng được tra cứu trong một thư mục con thuộc thư mục hồ sơ người dùng có tên là NativeMessagingHosts
.
- OS X (toàn hệ thống)
- Google Chrome:
/Library/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
- Chromium:
/Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
- Google Chrome:
- OS X (đường dẫn mặc định dành riêng cho người dùng)
- 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
- Google Chrome:
- Linux (toàn hệ thống)
- 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
- Google Chrome:
- Linux (đường dẫn mặc định dành riêng cho người dùng)
- Google Chrome:
~/.config/google-chrome/NativeMessagingHosts/_com.my_company.my_application_.json
- Chromium:
~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json
- Google Chrome:
Giao thức nhắn tin gốc
Chrome khởi động từng máy chủ thông báo gốc trong một quy trình riêng và giao tiếp với máy chủ đó bằng phương thức nhập tiêu chuẩn (stdin
) và đầu ra tiêu chuẩn (stdout
). Định dạng tương tự được dùng để gửi thông báo theo cả hai hướng: mỗi thông báo được chuyển đổi tuần tự bằng JSON, được mã hoá UTF-8 và đứng sau độ dài thông báo 32 bit theo thứ tự byte gốc. Kích thước tối đa của một thông báo từ máy chủ nhắn tin gốc là 1 MB, chủ yếu để bảo vệ Chrome khỏi các ứng dụng gốc hoạt động không đúng cách. Kích thước tối đa của tin nhắn gửi đến máy chủ nhắn tin gốc là 4 GB.
Đối số đầu tiên cho máy chủ nhắn tin gốc là nguồn gốc của phương thức gọi, thường là chrome-extension://[ID of allowed extension]
. Điều này cho phép các máy chủ nhắn tin gốc xác định nguồn của thông báo khi có nhiều tiện ích được chỉ định trong khoá allowed_origins
trong tệp kê khai của máy chủ nhắn tin gốc.
Cảnh báo: Trong Windows, trong Chrome 54 trở xuống, nguồn gốc được chuyển dưới dạng tham số thứ hai thay vì tham số đầu tiên.
Khi một cổng nhắn tin được tạo bằng runtime.connectNative, Chrome sẽ bắt đầu quy trình lưu trữ nhắn tin gốc và tiếp tục chạy cho đến khi cổng bị huỷ bỏ. Mặt khác, khi một thông báo được gửi bằng runtime.sendNativeMessage mà không tạo cổng nhắn tin, Chrome sẽ bắt đầu một quy trình lưu trữ thông báo gốc mới cho từng thông báo. Trong trường hợp đó, thông báo đầu tiên do quy trình lưu trữ tạo sẽ được xử lý dưới dạng phản hồi cho yêu cầu ban đầu, tức là Chrome sẽ chuyển thông báo đó đến lệnh gọi lại phản hồi được chỉ định khi gọi runtime.sendNativeMessage. Trong trường hợp đó, tất cả các thông báo khác do máy chủ nhắn tin gốc tạo ra đều sẽ bị bỏ qua.
Trên Windows, máy chủ nhắn tin gốc cũng được truyền một đối số dòng lệnh có ô điều khiển đến cửa sổ gốc Chrome đang gọi: --parent-window=<decimal handle value>
. Việc này cho phép máy chủ nhắn tin gốc tạo các cửa sổ giao diện người dùng gốc được phân cấp chính xác. Lưu ý rằng giá trị này sẽ bằng 0 nếu ngữ cảnh gọi là trang tập lệnh nền.
Kết nối với ứng dụng gốc
Việc gửi và nhận thông báo đến và từ một ứng dụng gốc rất giống với việc gửi và nhận thông báo trên nhiều tiện ích. Điểm khác biệt chính là runtime.connectNative được sử dụng thay cho runtime.connect và runtime.sendNativeMessage được sử dụng thay cho runtime.sendMessage. Bạn chỉ có thể sử dụng các phương thức này nếu quyền "nativeMessaging" được khai báo trong tệp kê khai của ứng dụng.
Ví dụ sau đây sẽ tạo một đối tượng runtime.Port được kết nối với máy chủ nhắn tin gốc com.my_company.my_application
, bắt đầu lắng nghe thông báo từ cổng đó và gửi một thông báo gửi đi:
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" });
Bạn có thể sử dụng runtime.sendNativeMessage để gửi thông báo đến ứng dụng gốc mà không cần tạo cổng, ví dụ:
chrome.runtime.sendNativeMessage('com.my_company.my_application',
{ text: "Hello" },
function(response) {
console.log("Received " + response);
});
Gỡ lỗi thông báo gốc
Khi máy chủ nhắn tin gốc không khởi động được, ghi vào stderr
hoặc khi máy chủ đó vi phạm giao thức giao tiếp, kết quả sẽ được ghi vào nhật ký lỗi của Chrome. Trên Linux và OS X, bạn có thể dễ dàng truy cập nhật ký này bằng cách khởi động Chrome qua dòng lệnh và xem kết quả của nhật ký này trong thiết bị đầu cuối. Trên Windows, hãy sử dụng --enable-logging
như giải thích trong bài viết Cách bật tính năng ghi nhật ký.
Dưới đây là một số lỗi và mẹo để giải quyết vấn đề:
- Không khởi động được máy chủ nhắn tin gốc.
- Kiểm tra xem bạn có đủ quyền để thực thi tệp hay không.
- Đã chỉ định tên máy chủ nhắn tin gốc không hợp lệ.
- Kiểm tra xem tên có chứa ký tự không hợp lệ nào không. Chỉ cho phép các ký tự chữ-số viết thường, dấu gạch dưới và dấu chấm. Tên không được bắt đầu hoặc kết thúc bằng một dấu chấm và theo sau không được là một dấu chấm khác.
- Máy chủ gốc đã thoát.
- Đường dẫn đến máy chủ nhắn tin gốc bị lỗi trước khi Chrome đọc thông báo. Nhiều khả năng quá trình này sẽ được bắt đầu từ máy chủ nhắn tin gốc.
- Không tìm thấy máy chủ nhắn tin gốc được chỉ định.
- Tên có được viết đúng chính tả trong tiện ích và trong tệp kê khai không?
- Tệp kê khai có được đặt vào đúng thư mục và đúng tên không? Xem vị trí lưu trữ tin nhắn gốc để biết các định dạng dự kiến.
- Tệp kê khai có đúng định dạng không? Cụ thể, cú pháp JSON có chính xác không và các giá trị có khớp với định nghĩa của tệp kê khai máy chủ nhắn tin gốc không?
- Tệp được chỉ định trong
path
có tồn tại không? Trên Windows, đường dẫn có thể là tương đối, nhưng trên OS X và Linux, đường dẫn phải là tuyệt đối.
- Tên máy chủ của máy chủ nhắn tin gốc chưa được đăng ký. (Chỉ dành cho Windows)
- Không tìm thấy máy chủ nhắn tin gốc trong sổ đăng ký Windows. Kiểm tra kỹ bằng
regedit
xem khoá có thực sự được tạo và khớp với định dạng bắt buộc như trong vị trí lưu trữ tin nhắn gốc hay không.
- Không tìm thấy máy chủ nhắn tin gốc trong sổ đăng ký Windows. Kiểm tra kỹ bằng
- Cấm truy cập vào máy chủ nhắn tin gốc đã chỉ định.
- Nguồn gốc của tiện ích có được liệt kê trong
allowed_origins
không?
- Nguồn gốc của tiện ích có được liệt kê trong
- Lỗi khi kết nối với máy chủ nhắn tin gốc.
- Đây là một lỗi rất phổ biến và chỉ ra việc triển khai giao thức liên lạc không chính xác trong máy chủ nhắn tin gốc.
- Đảm bảo tất cả đầu ra trong
stdout
đều tuân thủ giao thức nhắn tin gốc. Nếu bạn muốn in một số dữ liệu cho mục đích gỡ lỗi, hãy ghi vàostderr
. - Hãy đảm bảo độ dài thông báo 32 bit có định dạng số nguyên gốc của nền tảng (little-endian/big-endian).
- Độ dài thông báo không được vượt quá 1024*1024.
- Kích thước của thư phải bằng với số byte trong thư. Giá trị này có thể khác với "độ dài" của một chuỗi vì các ký tự có thể được biểu thị bằng nhiều byte.
- Chỉ dành cho Windows: Đảm bảo chế độ I/O của chương trình đã được đặt thành
O_BINARY
. Theo mặc định, chế độ I/O làO_TEXT
sẽ làm hỏng định dạng thông báo dưới dạng ngắt dòng (\n
=0A
) được thay thế bằng phần kết thúc dòng kiểu Windows (\r\n
=0D 0A
). Bạn có thể thiết lập chế độ I/O bằng cách sử dụng__setmode
.