API Web Bluetooth cho phép các trang web giao tiếp với thiết bị Bluetooth.
Giả sử tôi cho bạn biết các trang web có thể kết nối với thiết bị Bluetooth ở gần thì sao theo cách an toàn và bảo đảm quyền riêng tư không? Bằng cách này, thiết bị theo dõi tần số tim, hát bóng đèn và thậm chí rùa có thể tương tác trực tiếp với trang web.
Cho đến nay, người dùng vẫn có thể tương tác với thiết bị Bluetooth chỉ dành cho các ứng dụng dành riêng cho nền tảng. Web Bluetooth API hướng đến thay đổi điều này và cũng mang nó đến trình duyệt web.
Trước khi bắt đầu
Tài liệu này giả định rằng bạn có một số kiến thức cơ bản về tình trạng Bluetooth yếu Năng lượng (BLE) và Hồ sơ thuộc tính chung hoạt động.
Mặc dù thông số kỹ thuật của Web Bluetooth API chưa hoàn thiện, thông số kỹ thuật các tác giả đang tích cực tìm kiếm các nhà phát triển nhiệt huyết dùng thử API này và đưa ra ý kiến phản hồi về quy cách và ý kiến phản hồi về việc triển khai.
Một số API của Web Bluetooth API đã có trong ChromeOS, Chrome dành cho Android 6.0, Mac (Chrome 56) và Windows 10 (Chrome 70). Điều này có nghĩa là bạn sẽ có thể để yêu cầu và kết nối với thiết bị Bluetooth năng lượng thấp ở gần, đọc/ghi các đặc điểm Bluetooth, nhận được thông báo của GATT, biết rằng khi thiết bị Bluetooth bị ngắt kết nối và thậm chí đọc và ghi vào Bộ mô tả Bluetooth. Xem bảng Khả năng tương thích với trình duyệt của MDN để biết thêm thông tin của bạn.
Đối với Linux và các phiên bản Windows cũ hơn, hãy bật
Cờ #experimental-web-platform-features
trong about://flags
.
Có cho bản dùng thử theo nguyên gốc
Để nhận được nhiều phản hồi nhất có thể từ các nhà phát triển sử dụng Web Bluetooth API trong trường, Chrome đã thêm tính năng này vào Chrome trước đây 53 dưới dạng bản dùng thử theo nguyên gốc cho ChromeOS, Android và Mac.
Thử nghiệm đã kết thúc thành công vào tháng 1 năm 2017.
Yêu cầu về bảo mật
Để hiểu được các đánh đổi về bảo mật, tôi khuyên bạn nên dùng giải pháp Bảo mật web Bluetooth Lập mô hình bài đăng của Jeffrey Yasskin, một kỹ sư phần mềm trong nhóm Chrome, đang nghiên cứu thông số kỹ thuật của Web Bluetooth API.
Chỉ HTTPS
Do API thử nghiệm này là một tính năng mới mạnh mẽ được thêm vào web, API này chỉ dùng được cho bối cảnh an toàn. Điều này có nghĩa là bạn sẽ cần tạo bằng TLS.
Yêu cầu cử chỉ của người dùng
Là một tính năng bảo mật, việc phát hiện các thiết bị Bluetooth qua
navigator.bluetooth.requestDevice
phải được kích hoạt bằng một cử chỉ của người dùng, chẳng hạn như
dưới dạng một thao tác chạm hoặc nhấp chuột. Chúng ta đang nói về việc nghe
Sự kiện pointerup
, click
và touchend
.
button.addEventListener('pointerup', function(event) {
// Call navigator.bluetooth.requestDevice
});
Tìm hiểu về mã
Web Bluetooth API chủ yếu dựa vào JavaScript Promise (Lời hứa) của JavaScript. Nếu bạn không
hãy xem hướng dẫn về Cam kết tuyệt vời này. Một điều nữa,
() => {}
là các hàm mũi tên của ECMAScript 2015.
Yêu cầu thiết bị Bluetooth
Phiên bản này của thông số kỹ thuật Web Bluetooth API cho phép các trang web, chạy trong vai trò Trung tâm để kết nối với Máy chủ GATT từ xa qua kết nối BLE. Nó hỗ trợ giao tiếp giữa các thiết bị triển khai Bluetooth 4.0 trở lên.
Khi một trang web yêu cầu quyền truy cập vào các thiết bị ở gần bằng
navigator.bluetooth.requestDevice
, trình duyệt sẽ nhắc người dùng bằng một thiết bị
trình chọn nơi họ có thể chọn một thiết bị hoặc huỷ yêu cầu.
Hàm navigator.bluetooth.requestDevice()
nhận một đối tượng bắt buộc
xác định bộ lọc. Các bộ lọc này được dùng để chỉ trả về các thiết bị khớp với một số
quảng cáo dịch vụ Bluetooth GATT và/hoặc tên thiết bị.
Bộ lọc dịch vụ
Ví dụ: để yêu cầu các thiết bị Bluetooth quảng cáo Bluetooth GATT Dịch vụ pin:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Nếu Dịch vụ Bluetooth GATT của bạn không có trong danh sách Bluetooth chuẩn hoá Tuy nhiên, với dịch vụ GATT, bạn có thể cung cấp mã nhận dạng duy nhất (UUID) Bluetooth đầy đủ hoặc Dạng 16 hoặc 32 bit.
navigator.bluetooth.requestDevice({
filters: [{
services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
}]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Bộ lọc tên
Bạn cũng có thể yêu cầu thiết bị Bluetooth dựa trên tên thiết bị đang được quảng cáo
bằng khoá bộ lọc name
hoặc thậm chí là một tiền tố của tên này kèm theo namePrefix
phím bộ lọc. Lưu ý rằng trong trường hợp này, bạn cũng cần phải xác định
Khoá optionalServices
để có thể truy cập bất kỳ dịch vụ nào không có trong
bộ lọc dịch vụ. Nếu không, sau này bạn sẽ gặp lỗi khi cố truy cập
chúng.
navigator.bluetooth.requestDevice({
filters: [{
name: 'Francois robot'
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Bộ lọc dữ liệu nhà sản xuất
Bạn cũng có thể yêu cầu thiết bị Bluetooth dựa trên nhà sản xuất
dữ liệu cụ thể đang được quảng cáo bằng khoá bộ lọc manufacturerData
. Chìa khoá này
là một mảng các đối tượng có khoá mã nhận dạng công ty Bluetooth bắt buộc được đặt tên
companyIdentifier
. Bạn cũng có thể cung cấp tiền tố dữ liệu để lọc
dữ liệu của nhà sản xuất từ các thiết bị Bluetooth bắt đầu bằng thiết bị đó. Xin lưu ý rằng bạn sẽ
cũng cần xác định khoá optionalServices
để có thể truy cập bất cứ dịch vụ nào
không có trong bộ lọc dịch vụ. Nếu không, sau này bạn sẽ gặp lỗi khi
cố gắng truy cập chúng.
// Filter Bluetooth devices from Google company with manufacturer data bytes
// that start with [0x01, 0x02].
navigator.bluetooth.requestDevice({
filters: [{
manufacturerData: [{
companyIdentifier: 0x00e0,
dataPrefix: new Uint8Array([0x01, 0x02])
}]
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Bạn cũng có thể sử dụng mặt nạ với tiền tố dữ liệu để khớp một số mẫu trong dữ liệu của nhà sản xuất. Hãy xem tài liệu giải thích về bộ lọc dữ liệu Bluetooth để tìm hiểu khác.
Bộ lọc loại trừ
Lựa chọn exclusionFilters
trong navigator.bluetooth.requestDevice()
cho phép
bạn loại trừ một số thiết bị khỏi bộ chọn của trình duyệt. Bạn có thể sử dụng phương pháp này để loại trừ
thiết bị phù hợp với bộ lọc rộng hơn nhưng không được hỗ trợ.
// Request access to a bluetooth device whose name starts with "Created by".
// The device named "Created by Francois" has been reported as unsupported.
navigator.bluetooth.requestDevice({
filters: [{
namePrefix: "Created by"
}],
exclusionFilters: [{
name: "Created by Francois"
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Không dùng bộ lọc
Cuối cùng, thay vì filters
, bạn có thể sử dụng khoá acceptAllDevices
để hiện tất cả
thiết bị Bluetooth ở gần. Bạn cũng cần xác định optionalServices
để có thể truy cập một số dịch vụ. Nếu không thì sau này bạn sẽ thấy thông báo lỗi
khi cố gắng truy cập chúng.
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Kết nối với thiết bị Bluetooth
Vậy giờ bạn cần làm gì khi có BluetoothDevice
? Hãy kết nối với
Máy chủ GATT từ xa qua Bluetooth chứa dịch vụ và đặc điểm
định nghĩa.
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => {
// Human-readable name of the device.
console.log(device.name);
// Attempts to connect to remote GATT Server.
return device.gatt.connect();
})
.then(server => { /* … */ })
.catch(error => { console.error(error); });
Đọc đặc điểm Bluetooth
Ở đây, chúng ta kết nối với Máy chủ GATT của thiết bị Bluetooth từ xa. Giờ đây, chúng tôi muốn nhận một Dịch vụ GATT chính và đọc một đặc điểm thuộc về dịch vụ này. Ví dụ: hãy thử đọc mức phí hiện tại của pin của thiết bị.
Trong ví dụ phía trước, battery_level
là Mức pin tiêu chuẩn hoá
Đặc điểm.
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => device.gatt.connect())
.then(server => {
// Getting Battery Service…
return server.getPrimaryService('battery_service');
})
.then(service => {
// Getting Battery Level Characteristic…
return service.getCharacteristic('battery_level');
})
.then(characteristic => {
// Reading Battery Level…
return characteristic.readValue();
})
.then(value => {
console.log(`Battery percentage is ${value.getUint8(0)}`);
})
.catch(error => { console.error(error); });
Nếu sử dụng đặc điểm GATT Bluetooth tuỳ chỉnh, bạn có thể cung cấp
UUID Bluetooth đầy đủ hoặc biểu mẫu 16 hoặc 32 bit ngắn để
service.getCharacteristic
.
Xin lưu ý rằng bạn cũng có thể thêm trình nghe sự kiện characteristicvaluechanged
trên
để xử lý việc đọc giá trị của nó. Hãy khám phá Đặc điểm đọc
Mẫu đã thay đổi giá trị để xem cách xử lý GATT sắp tới (không bắt buộc)
thông báo.
…
.then(characteristic => {
// Set up event listener for when characteristic value changes.
characteristic.addEventListener('characteristicvaluechanged',
handleBatteryLevelChanged);
// Reading Battery Level…
return characteristic.readValue();
})
.catch(error => { console.error(error); });
function handleBatteryLevelChanged(event) {
const batteryLevel = event.target.value.getUint8(0);
console.log('Battery percentage is ' + batteryLevel);
}
Ghi vào một đặc điểm Bluetooth
Việc viết sang Đặc điểm của GATT Bluetooth cũng dễ dàng như đọc nó. Lần này, hãy sử dụng Điểm kiểm soát tần số tim để đặt lại giá trị của Mức năng lượng chi tiêu về 0 trên thiết bị theo dõi nhịp tim.
Tôi hứa không có phép thuật nào ở đây. Điều này được giải thích trong bài viết Kiểm soát tần số tim Trang Đặc điểm của điểm.
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('heart_rate'))
.then(service => service.getCharacteristic('heart_rate_control_point'))
.then(characteristic => {
// Writing 1 is the signal to reset energy expended.
const resetEnergyExpended = Uint8Array.of(1);
return characteristic.writeValue(resetEnergyExpended);
})
.then(_ => {
console.log('Energy expended has been reset.');
})
.catch(error => { console.error(error); });
Nhận thông báo về GATT
Bây giờ, hãy xem cách nhận thông báo khi chỉ số Đo lường tần số tim các thay đổi về đặc điểm trên thiết bị:
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('heart_rate'))
.then(service => service.getCharacteristic('heart_rate_measurement'))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
characteristic.addEventListener('characteristicvaluechanged',
handleCharacteristicValueChanged);
console.log('Notifications have been started.');
})
.catch(error => { console.error(error); });
function handleCharacteristicValueChanged(event) {
const value = event.target.value;
console.log('Received ' + value);
// TODO: Parse Heart Rate Measurement value.
// See https://github.com/WebBluetoothCG/demos/blob/gh-pages/heart-rate-sensor/heartRateSensor.js
}
Mẫu thông báo hướng dẫn bạn cách ngừng nhận thông báo bằng
stopNotifications()
và xoá characteristicvaluechanged
đã thêm đúng cách
trình nghe sự kiện.
Ngắt kết nối khỏi thiết bị Bluetooth
Để mang lại trải nghiệm tốt hơn cho người dùng, bạn nên theo dõi các sự kiện ngắt kết nối và mời người dùng kết nối lại:
navigator.bluetooth.requestDevice({ filters: [{ name: 'Francois robot' }] })
.then(device => {
// Set up event listener for when device gets disconnected.
device.addEventListener('gattserverdisconnected', onDisconnected);
// Attempts to connect to remote GATT Server.
return device.gatt.connect();
})
.then(server => { /* … */ })
.catch(error => { console.error(error); });
function onDisconnected(event) {
const device = event.target;
console.log(`Device ${device.name} is disconnected.`);
}
Bạn cũng có thể gọi device.gatt.disconnect()
để ngắt kết nối ứng dụng web của mình khỏi
Thiết bị Bluetooth. Thao tác này sẽ kích hoạt sự kiện gattserverdisconnected
hiện có
người nghe. Lưu ý rằng thao tác này sẽ KHÔNG dừng hoạt động giao tiếp của thiết bị Bluetooth nếu có
ứng dụng đang kết nối với thiết bị Bluetooth. Hãy xem Thiết bị
Mẫu ngắt kết nối và Mẫu tự động kết nối lại để tìm hiểu sâu hơn.
Đọc và ghi vào bộ mô tả Bluetooth
Mã mô tả theo GATT Bluetooth là các thuộc tính mô tả một giá trị đặc điểm. Bạn có thể đọc và ghi vào theo cách tương tự như Bluetooth GATT đặc điểm.
Hãy xem ví dụ về cách đọc nội dung mô tả về số đo do người dùng tạo khoảng thời gian đo nhiệt kế sức khoẻ của thiết bị.
Trong ví dụ bên dưới, health_thermometer
là dịch vụ Nhiệt kế sức khoẻ,
measurement_interval
đặc tính Khoảng thời gian đo lường và
gatt.characteristic_user_description
Mô tả đặc trưng về người dùng
mã mô tả.
navigator.bluetooth.requestDevice({ filters: [{ services: ['health_thermometer'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('health_thermometer'))
.then(service => service.getCharacteristic('measurement_interval'))
.then(characteristic => characteristic.getDescriptor('gatt.characteristic_user_description'))
.then(descriptor => descriptor.readValue())
.then(value => {
const decoder = new TextDecoder('utf-8');
console.log(`User Description: ${decoder.decode(value)}`);
})
.catch(error => { console.error(error); });
Bây giờ, chúng ta đã đọc phần mô tả người dùng về khoảng thời gian đo lường của nhiệt kế sức khoẻ của thiết bị, hãy xem cách cập nhật và viết một giá trị.
navigator.bluetooth.requestDevice({ filters: [{ services: ['health_thermometer'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('health_thermometer'))
.then(service => service.getCharacteristic('measurement_interval'))
.then(characteristic => characteristic.getDescriptor('gatt.characteristic_user_description'))
.then(descriptor => {
const encoder = new TextEncoder('utf-8');
const userDescription = encoder.encode('Defines the time between measurements.');
return descriptor.writeValue(userDescription);
})
.catch(error => { console.error(error); });
Mẫu, bản minh hoạ và lớp học lập trình
Tất cả mẫu Bluetooth trên web bên dưới đã được kiểm tra thành công. Để thưởng thức những trò chơi này tối đa các mẫu, tôi khuyên bạn nên cài đặt [Trình mô phỏng thiết bị ngoại vi BLE Ứng dụng Android] mô phỏng thiết bị ngoại vi BLE có Dịch vụ pin, Nhịp tim hoặc Dịch vụ nhiệt kế sức khoẻ.
Cơ bản
- Thông tin thiết bị – truy xuất thông tin cơ bản về thiết bị từ thiết bị BLE.
- Mức pin – truy xuất thông tin về pin từ thông tin Pin quảng cáo của thiết bị BLE.
- Đặt lại năng lượng – đặt lại năng lượng đã tiêu thụ từ Nhịp tim cho quảng cáo trên thiết bị BLE.
- Characteristic Properties (Thuộc tính đặc trưng) – hiển thị tất cả các thuộc tính của một đặc điểm cụ thể trên Thiết bị BLE.
- Thông báo – bắt đầu và dừng các thông báo đặc trưng từ thiết bị BLE.
- Ngắt kết nối thiết bị – hãy ngắt kết nối và nhận thông báo về việc ngắt kết nối thiết bị BLE sau khi kết nối với thiết bị đó.
- Get Characteristics (Khám phá các đặc điểm) – xem tất cả các đặc điểm của một dịch vụ được quảng cáo từ một Thiết bị BLE.
- Nhận từ khóa mô tả – tìm hiểu tất cả các đặc điểm mã mô tả của một dịch vụ được quảng cáo từ Thiết bị BLE.
- Bộ lọc dữ liệu nhà sản xuất – truy xuất thông tin cơ bản về thiết bị từ Thiết bị BLE khớp với dữ liệu của nhà sản xuất.
- Bộ lọc loại trừ - truy xuất thông tin cơ bản về thiết bị từ Thiết bị BLE có các bộ lọc loại trừ cơ bản.
Kết hợp nhiều phép toán
- Đặc điểm GAP – nhận được tất cả các đặc điểm GAP của Thiết bị BLE.
- Device Information Characteristics (Đặc điểm thông tin thiết bị) – nhận được tất cả đặc điểm về Thông tin thiết bị của thiết bị BLE.
- Mất liên kết – đặt đặc tính Mức cảnh báo của Thiết bị BLE (readValue và writeValue).
- Khám phá các dịch vụ và Đặc điểm – khám phá tất cả các dịch vụ chính có thể truy cập và đặc điểm của các dịch vụ đó trên một Thiết bị BLE.
- Tự động kết nối lại – kết nối lại với một thiết bị BLE đã ngắt kết nối bằng thuật toán thời gian đợi luỹ thừa.
- Đọc giá trị đặc trưng đã thay đổi – đọc mức pin và nhận thông báo về những thay đổi từ Thiết bị BLE.
- Đọc nội dung mô tả – đọc tất cả nội dung mô tả đặc điểm của một dịch vụ trên Thiết bị BLE.
- Viết mô tả – ghi vào phần mô tả "Characteristic User Description" trên thiết bị BLE.
Ngoài ra, hãy xem Bản minh hoạ về Bluetooth trên web được tuyển chọn cũng như Lớp học lập trình chính thức về Bluetooth trên web.
Thư viện
- web-bluetooth-utils là một mô-đun npm giúp thêm một số hàm tiện lợi vào API.
- Miếng đệm API Web Bluetooth có sẵn ở noble, BLE Node.js phổ biến nhất mô-đun trung tâm. Điều này cho phép bạn xây dựng webpack/trình duyệt cao cấp mà không cần dành cho máy chủ WebSocket hoặc các trình bổ trợ khác.
- angular-web-bluetooth là một mô-đun dành cho Angular, giúp loại bỏ mọi thông tin Cần có mã nguyên mẫu để định cấu hình Web Bluetooth API.
Công cụ
- Bắt đầu với Web Bluetooth là một Ứng dụng web đơn giản sẽ tạo tất cả mã nguyên mẫu JavaScript để bắt đầu tương tác với thiết bị Bluetooth. Nhập tên thiết bị, dịch vụ, đặc điểm, xác định các thuộc tính và bạn đã sẵn sàng.
- Nếu bạn đã là nhà phát triển Bluetooth, Web Bluetooth Developer Studio Plugin cũng sẽ tạo mã JavaScript Web Bluetooth cho Thiết bị Bluetooth.
Mẹo
Trang Bluetooth nội bộ có trong Chrome tại
about://bluetooth-internals
để bạn có thể kiểm tra mọi thứ về lân cận
Thiết bị Bluetooth: trạng thái, dịch vụ, đặc điểm và mã mô tả.
Bạn cũng nên xem Cách báo cáo lỗi Bluetooth trên web vì đôi khi, việc gỡ lỗi Bluetooth có thể khó khăn.
Các bước tiếp theo
Trước tiên, hãy kiểm tra trạng thái triển khai trình duyệt và nền tảng để biết phần nào của Web Bluetooth API hiện đang được triển khai.
Mặc dù địa điểm này vẫn chưa hoàn chỉnh, nhưng sau đây là một phần giới thiệu về các hoạt động trong tương lai gần tương lai:
- Quét tìm quảng cáo BLE ở gần
sẽ xảy ra với
navigator.bluetooth.requestLEScan()
. - Một sự kiện
serviceadded
mới sẽ theo dõi các Dịch vụ Bluetooth GATT mới được phát hiện trong khiserviceremoved
sự kiện sẽ theo dõi những sự kiện bị xoá. Mộtservicechanged
mới sẽ kích hoạt khi bất kỳ đặc điểm và/hoặc nội dung mô tả nào được thêm vào hoặc đã bị xoá khỏi Dịch vụ Bluetooth GATT.
Hiện thông tin hỗ trợ về API này
Bạn có định dùng API Web Bluetooth không? Sự hỗ trợ công khai của bạn giúp ích cho nhóm Chrome ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác biết tầm quan trọng của việc hỗ trợ các tính năng đó.
Gửi một bài đăng đến @ChromiumDev kèm theo hashtag
#WebBluetooth
đồng thời cho chúng tôi biết bạn đang sử dụng ứng dụng đó ở đâu và như thế nào.
Tài nguyên
- Stack Overflow
- Trạng thái của tính năng Chrome
- Lỗi triển khai Chrome
- Thông số kỹ thuật Bluetooth cho web
- Quy cách các vấn đề trên GitHub
- Ứng dụng Trình mô phỏng thiết bị ngoại vi BLE
Xác nhận
Cảm ơn Kayce Basques đã xem xét bài viết này. Hình ảnh chính của SparkFun Electronics ở Boulder, Hoa Kỳ.