Tiện ích 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ột máy chủ nhắn tin gốc có thể giao tiếp với tiện ích. Chrome khởi động máy chủ lưu trữ trong một quy trình riêng biệt và giao tiếp với máy chủ đó bằng cách sử dụng luồng đầu vào tiêu chuẩn và luồng đầu ra tiêu chuẩn.
Máy chủ nhắn tin gốc
Để đăng ký một máy chủ nhắn tin gốc, ứng dụng phải lưu một tệp xác định cấu hình máy chủ nhắn tin gốc.
Sau đây là ví dụ về tệp này:
{
"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ủ nhắn tin gốc phải là JSON hợp lệ và chứa các trường sau:
name- Tên của máy chủ nhắn tin gốc. Các ứng dụng sẽ truyền chuỗi này đến
runtime.connectNative()hoặcruntime.sendNativeMessage(). Tên này chỉ có thể chứa các ký tự chữ và 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 dấu chấm, đồng thời dấu chấm không được theo sau bởi 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à macOS, đường dẫn phải là đường dẫn tuyệt đối. Trên Windows, đường dẫn này có thể tương ứng với thư mục chứa tệp kê khai. Tiến trình máy chủ được bắt đầu khi thư mục hiện tại được đặt thành thư mục chứa tệp nhị phân máy chủ. Ví dụ: nếu bạn đặt tham số này thành
C:\Application\nm_host.exethì tham số này sẽ 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ủ lưu trữ nhắn tin gốc. Tham số này có một giá trị có thể:
stdio. Điều này cho biết Chrome nên sử dụngstdinvàstdoutđể giao tiếp với máy chủ lưu trữ. allowed_origins- Danh sách các tiện ích cần có quyền truy cập vào máy chủ nhắn tin gốc. Giá trị
allowed-originskhông được chứa ký tự đại diện.
Vị trí của 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 kỳ vị trí nào trong hệ thống tệp. Trình cài đặt ứng dụng phải tạo một khoá đăng ký, có thể là 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, đồng thời đặ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 đây:
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, Chrome sẽ truy vấn sổ đăng ký 32 bit, sau đó là sổ đăng ký 64 bit.
Trên macOS và Linux, vị trí của tệp kê khai máy chủ nhắn tin gốc sẽ tuỳ thuộc vào 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 thư mục con NativeMessagingHosts/ của thư mục hồ sơ người dùng.
- macOS (trên 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 - macOS (dành riêng cho người dùng, đường dẫn mặc định)
- 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 (trên 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 - Linux (dành riêng cho người dùng, đường dẫn mặc định)
- Google Chrome:
~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json
Giao thức nhắn tin gốc
Chrome khởi động từng máy chủ nhắn tin gốc trong một quy trình riêng biệt và giao tiếp với máy chủ đó bằng cách sử dụng đầu vào chuẩn (stdin) và đầu ra chuẩn (stdout). Cùng một định dạng đượ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 trước độ 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ư duy nhất 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 thông báo được gửi đến máy chủ nhắn tin gốc là 64 MiB.
Đối số đầu tiên cho máy chủ nhắn tin gốc là nguồn gốc của người 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 nhiều tiện ích được chỉ định trong khoá allowed_origins trong tệp kê khai máy chủ nhắn tin gốc.
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ó một hàm xử lý đến cửa sổ gốc Chrome đang gọi: --parent-window=<decimal handle value>. Điều 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 liên kết đúng cách. Xin lưu ý rằng giá trị này sẽ là 0 nếu ngữ cảnh gọi là một worker dịch vụ.
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ữ tin nhắn gốc và duy trì quy trình này cho đến khi cổng bị huỷ. 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 mỗi 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 ra sẽ được xử lý dưới dạng phản hồi cho yêu cầu ban đầu và Chrome sẽ truyền thông báo đó đến lệnh gọi lại phản hồi được chỉ định khi runtime.sendNativeMessage() được gọi. 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 bị bỏ qua.
Kết nối với một ứng dụng gốc
Việc gửi và nhận thông báo đến và đi từ một ứng dụng gốc rất giống với việc truyền thông báo giữa các tiện ích. Điểm khác biệt chính là runtime.connectNative() được dùng thay cho runtime.connect() và runtime.sendNativeMessage() được dùng thay cho runtime.sendMessage().
Để sử dụng các phương thức này, bạn phải khai báo quyền "nativeMessaging" trong tệp kê khai của tiện ích.
Các phương thức này không có trong tập lệnh nội dung mà chỉ có trong các trang và trình chạy dịch vụ của tiện ích. Nếu bạn muốn giao tiếp từ một tập lệnh nội dung đến ứng dụng gốc, hãy gửi thông báo đến worker dịch vụ để chuyển thông báo đó đến ứng dụng gốc.
Ví dụ sau đây tạo một đối tượng runtime.Port được kết nối với máy chủ lưu trữ nhắn tin gốc com.my_company.my_application, bắt đầu theo dõi các thông báo từ cổng đó và gửi một thông báo đ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'});
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 tính năng nhắn tin gốc
Khi xảy ra một số lỗi nhắn tin gốc, đầu ra sẽ được ghi vào nhật ký lỗi của Chrome. Điều này bao gồm cả trường hợp máy chủ nhắn tin gốc không khởi động được, ghi vào stderr hoặc vi phạm giao thức giao tiếp. Trên Linux và macOS, bạn có thể truy cập nhật ký này bằng cách khởi động Chrome từ dòng lệnh và xem đầu ra của nhật ký trong thiết bị đầu cuối. Trên Windows, hãy sử dụng --enable-logging như được giải thích trong phần Cách bật tính năng ghi nhật ký.
Sau đây là một số lỗi thường gặp và mẹo khắc phục:
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 máy chủ nhắn tin gốc hay không.
Tên máy chủ nhắn tin gốc không hợp lệ đã được chỉ định.
Kiểm tra xem tên có chứa ký tự không hợp lệ hay không. Chỉ được dùng 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 dấu chấm và dấu chấm không được theo sau bởi một dấu chấm khác.
Máy chủ gốc đã thoát.
Đường ống dẫn đến máy chủ nhắn tin gốc bị hỏng trước khi Chrome đọc được thông báo. Điều này thường bắt nguồn từ máy chủ nhắn tin gốc của bạn.
Không tìm thấy máy chủ nhắn tin gốc được chỉ định.
Kiểm tra những điều sau:
- 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ó nằm trong đúng thư mục và có tên chính xác không? Hãy xem vị trí của máy chủ nhắn tin 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ể, JSON có hợp lệ và được định dạng đúng hay không và các giá trị có khớp với định nghĩa về tệp kê khai máy chủ nhắn tin gốc hay không?
- Tệp được chỉ định trong
pathcó tồn tại không? Trên Windows, đường dẫn có thể là đường dẫn tương đối, nhưng trên macOS và Linux, đường dẫn phải là đường dẫn tuyệt đối.
Tên máy chủ lưu trữ 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 cách sử dụng regedit xem khoá có thực sự được tạo và có khớp với định dạng bắt buộc như được ghi lại tại vị trí máy chủ nhắn tin gốc hay không.
Không được phép 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?
Đã xảy ra lỗi khi giao tiếp với máy chủ nhắn tin gốc.
Điều này cho biết việc triển khai giao thức giao tiếp không chính xác trong máy chủ nhắn tin gốc.
- Đảm bảo rằng 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. - Đảm bảo rằng độ dài thông báo 32 bit ở định dạng số nguyên gốc của nền tảng (little-endian/big-endian).
- Độ dài của thông báo không được vượt quá 1024*1024.
- Kích thước thông báo phải bằng số byte trong thông báo. Điều 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 rằng 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, chế độ này làm hỏng định dạng thông báo vì dấu ngắt dòng (\n=0A) được thay thế bằng dấu kết thúc dòng theo kiểu Windows (\r\n=0D 0A). Bạn có thể đặt chế độ I/O bằng cách sử dụng__setmode.