การสื่อสารกับอุปกรณ์บลูทูธผ่าน JavaScript

Web Bluetooth API ช่วยให้เว็บไซต์สื่อสารกับอุปกรณ์บลูทูธได้

François Beaufort
François Beaufort

จะเกิดอะไรขึ้นหากฉันบอกว่าเว็บไซต์สามารถสื่อสารกับอุปกรณ์บลูทูธที่อยู่ใกล้เคียง ได้อย่างปลอดภัยและรักษาความเป็นส่วนตัว ด้วยวิธีนี้ เครื่องวัดอัตราการเต้นของหัวใจ หลอดไฟที่ร้องเพลงได้ และแม้แต่เต่าก็สามารถโต้ตอบกับเว็บไซต์ได้โดยตรง

ก่อนหน้านี้ ความสามารถในการโต้ตอบกับอุปกรณ์บลูทูธใช้ได้เฉพาะกับแอปที่เจาะจงแพลตฟอร์มเท่านั้น Web Bluetooth API มีเป้าหมายที่จะเปลี่ยนแปลงสิ่งนี้และ นำมาใช้กับเว็บเบราว์เซอร์ด้วย

ก่อนที่จะเริ่ม

เอกสารนี้ถือว่าคุณมีความรู้พื้นฐานเกี่ยวกับวิธีที่บลูทูธพลังงานต่ำ (BLE) และโปรไฟล์แอตทริบิวต์ทั่วไปทำงาน

แม้ว่าข้อกำหนดของ Web Bluetooth API จะยังไม่เสร็จสมบูรณ์ แต่ผู้เขียนข้อกำหนด กำลังมองหานักพัฒนาแอปที่กระตือรือร้นเพื่อลองใช้ API นี้และแสดงความคิดเห็นเกี่ยวกับข้อกำหนด รวมถึงแสดงความคิดเห็นเกี่ยวกับการใช้งาน

API ของ Web Bluetooth บางส่วนพร้อมใช้งานใน ChromeOS, Chrome สำหรับ Android 6.0, Mac (Chrome 56) และ Windows 10 (Chrome 70) ซึ่งหมายความว่าคุณควรจะขอและเชื่อมต่อกับอุปกรณ์บลูทูธพลังงานต่ำที่อยู่ใกล้เคียงได้ อ่าน/เขียนลักษณะของบลูทูธ รับการแจ้งเตือน GATT ทราบเมื่ออุปกรณ์บลูทูธถูกตัดการเชื่อมต่อ และแม้กระทั่งอ่านและเขียนไปยังตัวอธิบายบลูทูธ ดูข้อมูลเพิ่มเติมได้ที่ตารางความเข้ากันได้ของเบราว์เซอร์ของ MDN

สำหรับ Linux และ Windows เวอร์ชันก่อนหน้า ให้เปิดใช้ฟีเจอร์#experimental-web-platform-featuresใน about://flags

พร้อมใช้งานสำหรับการทดลองใช้ต้นทาง

Chrome ได้เพิ่มฟีเจอร์นี้ใน Chrome 53 เป็นช่วงทดลองใช้จากต้นทางสำหรับ ChromeOS, Android และ Mac เพื่อรับความคิดเห็นจากนักพัฒนาซอฟต์แวร์ที่ใช้ Web Bluetooth API ในภาคสนามให้ได้มากที่สุด

การทดลองสิ้นสุดลงอย่างราบรื่นในเดือนมกราคม 2017

ข้อกำหนดด้านความปลอดภัย

หากต้องการทำความเข้าใจข้อแลกเปลี่ยนด้านความปลอดภัย เราขอแนะนำโพสต์โมเดลความปลอดภัยของ Web Bluetooth จาก Jeffrey Yasskin ซึ่งเป็นวิศวกรซอฟต์แวร์ในทีม Chrome ที่ทำงานเกี่ยวกับข้อกำหนดของ Web Bluetooth API

HTTPS เท่านั้น

เนื่องจาก API เวอร์ชันทดลองนี้เป็นฟีเจอร์ใหม่ที่มีประสิทธิภาพซึ่งเพิ่มลงในเว็บ เราจึงเปิดให้ใช้งานในบริบทที่ปลอดภัยเท่านั้น ซึ่งหมายความว่าคุณจะต้องสร้างโดยคำนึงถึง TLS

ต้องใช้ท่าทางสัมผัสของผู้ใช้

ในฐานะฟีเจอร์ด้านความปลอดภัย การค้นหาอุปกรณ์บลูทูธด้วย navigator.bluetooth.requestDevice ต้องเกิดจากท่าทางของผู้ใช้ เช่น การแตะหรือการคลิกเมาส์ เรากำลังพูดถึงการฟังเหตุการณ์ pointerup, click และ touchend

button.addEventListener('pointerup', function(event) {
  // Call navigator.bluetooth.requestDevice
});

เจาะลึกโค้ด

Web Bluetooth API อาศัย Promise ของ JavaScript เป็นอย่างมาก หากคุณไม่คุ้นเคยกับ Promise โปรดดูบทแนะนำเกี่ยวกับ Promise ที่ยอดเยี่ยมนี้ อีกอย่างหนึ่ง () => {} คือฟังก์ชันลูกศร ECMAScript 2015

ขออุปกรณ์บลูทูธ

ข้อกำหนดของ Web Bluetooth API เวอร์ชันนี้อนุญาตให้เว็บไซต์ที่ทำงานในบทบาทส่วนกลางเชื่อมต่อกับเซิร์ฟเวอร์ GATT ระยะไกลผ่านการเชื่อมต่อ BLE โดย รองรับการสื่อสารระหว่างอุปกรณ์ที่ใช้บลูทูธ 4.0 ขึ้นไป

เมื่อเว็บไซต์ขอสิทธิ์เข้าถึงอุปกรณ์ที่อยู่ใกล้เคียงโดยใช้ navigator.bluetooth.requestDevice เบราว์เซอร์จะแจ้งให้ผู้ใช้เลือกอุปกรณ์ ที่ต้องการ หรือยกเลิกคำขอ

ข้อความแจ้งผู้ใช้อุปกรณ์บลูทูธ

ฟังก์ชัน navigator.bluetooth.requestDevice() จะใช้ออบเจ็กต์ที่จำเป็นซึ่ง กำหนดตัวกรอง ตัวกรองเหล่านี้ใช้เพื่อแสดงเฉพาะอุปกรณ์ที่ตรงกับบริการ GATT ของบลูทูธที่โฆษณาและ/หรือชื่ออุปกรณ์

ตัวกรองบริการ

ตัวอย่างเช่น หากต้องการขออุปกรณ์บลูทูธที่โฆษณาบริการแบตเตอรี่ GATT ของบลูทูธ ให้ทำดังนี้

navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });

อย่างไรก็ตาม หากบริการ GATT ของบลูทูธไม่ได้อยู่ในรายการบริการ GATT ของบลูทูธที่ได้มาตรฐาน คุณอาจระบุ UUID ของบลูทูธแบบเต็มหรือแบบย่อ 16 หรือ 32 บิตก็ได้

navigator.bluetooth.requestDevice({
  filters: [{
    services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
  }]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

ตัวกรองชื่อ

นอกจากนี้ คุณยังขออุปกรณ์บลูทูธตามชื่ออุปกรณ์ที่โฆษณาได้ด้วยnameคีย์ตัวกรอง หรือแม้แต่คำนำหน้าของชื่อนี้ด้วยคีย์namePrefixตัวกรอง โปรดทราบว่าในกรณีนี้ คุณจะต้องกำหนดคีย์ optionalServices ด้วยเพื่อให้เข้าถึงบริการที่ไม่ได้รวมอยู่ในตัวกรองบริการได้ ไม่เช่นนั้น คุณจะได้รับข้อผิดพลาดในภายหลังเมื่อพยายามเข้าถึง ไฟล์ดังกล่าว

navigator.bluetooth.requestDevice({
  filters: [{
    name: 'Francois robot'
  }],
  optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

ตัวกรองข้อมูลผู้ผลิต

นอกจากนี้ คุณยังขออุปกรณ์บลูทูธตามข้อมูลเฉพาะของผู้ผลิตที่โฆษณาด้วยคีย์ manufacturerData filters ได้ด้วย คีย์นี้ เป็นอาร์เรย์ของออบเจ็กต์ที่มีคีย์ตัวระบุบริษัทบลูทูธที่จำเป็นชื่อ companyIdentifier นอกจากนี้ คุณยังระบุคำนำหน้าข้อมูลที่กรองข้อมูลผู้ผลิตจากอุปกรณ์บลูทูธที่เริ่มต้นด้วยคำนำหน้าดังกล่าวได้ด้วย โปรดทราบว่าคุณจะต้องกำหนดคีย์ optionalServices เพื่อเข้าถึงบริการที่ไม่ได้รวมอยู่ในตัวกรองบริการด้วย หากไม่ทำเช่นนั้น คุณจะได้รับข้อผิดพลาดในภายหลังเมื่อ พยายามเข้าถึงไฟล์

// 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); });

นอกจากนี้ ยังใช้มาสก์กับคำนำหน้าข้อมูลเพื่อจับคู่รูปแบบบางอย่างใน ข้อมูลของผู้ผลิตได้ด้วย ดูข้อมูลเพิ่มเติมได้ที่คำอธิบายตัวกรองข้อมูลบลูทูธ

ตัวกรองการยกเว้น

ตัวเลือก exclusionFilters ใน navigator.bluetooth.requestDevice() ช่วยให้คุณยกเว้นอุปกรณ์บางเครื่องจากตัวเลือกเบราว์เซอร์ได้ ใช้เพื่อยกเว้น อุปกรณ์ที่ตรงกับตัวกรองที่กว้างกว่าแต่ไม่รองรับได้

// 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); });

ไม่มีตัวกรอง

สุดท้ายนี้ คุณสามารถใช้ปุ่ม acceptAllDevices เพื่อแสดงอุปกรณ์บลูทูธทั้งหมดที่อยู่ใกล้เคียงแทน filters ได้ นอกจากนี้ คุณยังต้องกำหนดoptionalServices คีย์เพื่อเข้าถึงบริการบางอย่างได้ด้วย ไม่เช่นนั้น คุณจะได้รับข้อผิดพลาดในภายหลัง เมื่อพยายามเข้าถึง

navigator.bluetooth.requestDevice({
  acceptAllDevices: true,
  optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

เชื่อมต่อกับอุปกรณ์บลูทูธ

แล้วคุณควรทำอย่างไรเมื่อมี BluetoothDevice มาเชื่อมต่อกับเซิร์ฟเวอร์ GATT ของรีโมตบลูทูธซึ่งมีคำจำกัดความของบริการและลักษณะ กัน

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); });

อ่านลักษณะบลูทูธ

ในที่นี้ เราจะเชื่อมต่อกับเซิร์ฟเวอร์ GATT ของอุปกรณ์บลูทูธระยะไกล ตอนนี้เราต้องการรับบริการ GATT หลักและอ่านลักษณะที่อยู่ในบริการนี้ เช่น ลองอ่านระดับการชาร์จปัจจุบันของแบตเตอรี่ของอุปกรณ์

ในตัวอย่างต่อไปนี้ battery_level คือ ลักษณะระดับแบตเตอรี่ที่ได้มาตรฐาน

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); });

หากใช้ลักษณะ GATT ของบลูทูธที่กำหนดเอง คุณอาจระบุ UUID ของบลูทูธแบบเต็มหรือรูปแบบสั้น 16 หรือ 32 บิตให้กับ service.getCharacteristic

โปรดทราบว่าคุณยังเพิ่มเครื่องมือฟังเหตุการณ์ characteristicvaluechanged ในลักษณะเพื่อจัดการการอ่านค่าได้ด้วย ดูตัวอย่างการเปลี่ยนแปลงค่าลักษณะการอ่านเพื่อดูวิธีจัดการการแจ้งเตือน GATT ที่กำลังจะมาถึง (ไม่บังคับ)


.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);
}

เขียนไปยังลักษณะบลูทูธ

การเขียนไปยังลักษณะ GATT ของบลูทูธนั้นง่ายพอๆ กับการอ่าน คราวนี้ มาใช้จุดควบคุมอัตราการเต้นของหัวใจเพื่อรีเซ็ตค่าของช่อง พลังงานที่ใช้ไปเป็น 0 ในอุปกรณ์เครื่องวัดอัตราการเต้นของหัวใจกัน

รับรองว่าไม่มีเวทมนตร์ใดๆ ที่นี่ ซึ่งอธิบายไว้ทั้งหมดในหน้าลักษณะของจุดควบคุมอัตราการเต้นของหัวใจ

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); });

รับการแจ้งเตือน GATT

มาดูวิธีรับการแจ้งเตือนเมื่อลักษณะการวัดอัตราการเต้นของหัวใจ เปลี่ยนแปลงในอุปกรณ์กัน

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
}

ตัวอย่างการแจ้งเตือนจะแสดงวิธีหยุดการแจ้งเตือนด้วย stopNotifications() และนำcharacteristicvaluechanged เครื่องฟังกิจกรรมที่เพิ่มออกอย่างถูกต้อง

ยกเลิกการเชื่อมต่อจากอุปกรณ์บลูทูธ

หากต้องการมอบประสบการณ์การใช้งานที่ดีขึ้น คุณอาจต้องรอเหตุการณ์การตัดการเชื่อมต่อ และเชิญให้ผู้ใช้เชื่อมต่ออีกครั้ง

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.`);
}

คุณยังโทรหา device.gatt.disconnect() เพื่อยกเลิกการเชื่อมต่อเว็บแอปจาก อุปกรณ์บลูทูธได้ด้วย การดำเนินการนี้จะทริกเกอร์เครื่องมือฟังเหตุการณ์ gattserverdisconnected ที่มีอยู่ โปรดทราบว่าการดำเนินการนี้จะไม่หยุดการสื่อสารของอุปกรณ์บลูทูธหากแอปอื่น สื่อสารกับอุปกรณ์บลูทูธอยู่แล้ว ดูข้อมูลเพิ่มเติมได้ที่ตัวอย่างการยกเลิกการเชื่อมต่ออุปกรณ์และตัวอย่างการเชื่อมต่อใหม่โดยอัตโนมัติ

อ่านและเขียนไปยังตัวอธิบายบลูทูธ

ตัวอธิบาย GATT ของ Bluetooth คือแอตทริบิวต์ที่อธิบายค่าลักษณะ คุณอ่านและเขียนข้อมูลได้ในลักษณะเดียวกับลักษณะ GATT ของบลูทูธ

มาดูตัวอย่างวิธีอ่านคำอธิบายผู้ใช้ของช่วงการวัด อุณหภูมิสุขภาพของอุปกรณ์กัน

ในตัวอย่างด้านล่าง health_thermometer คือบริการเทอร์โมมิเตอร์วัดไข้ measurement_interval คือลักษณะช่วงเวลาการวัด และ gatt.characteristic_user_description คือตัวอธิบายลักษณะของผู้ใช้

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); });

ตอนนี้เราได้อ่านคำอธิบายของผู้ใช้เกี่ยวกับช่วงการวัดของเทอร์โมมิเตอร์วัดสุขภาพของอุปกรณ์แล้ว มาดูวิธีอัปเดตและเขียนค่าที่กำหนดเองกัน

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); });

ตัวอย่าง การสาธิต และ Codelab

เราได้ทดสอบตัวอย่าง Web Bluetooth ทั้งหมดด้านล่างเรียบร้อยแล้ว หากต้องการเพลิดเพลินกับตัวอย่างเหล่านี้อย่างเต็มที่ เราขอแนะนำให้คุณติดตั้ง [BLE Peripheral Simulator Android App] ซึ่งจำลองอุปกรณ์ BLE ที่มีบริการแบตเตอรี่ บริการอัตราการเต้นของหัวใจ หรือบริการเทอร์โมมิเตอร์วัดอุณหภูมิร่างกาย

ผู้เริ่มต้น

การรวมการดำเนินการหลายอย่าง

นอกจากนี้ โปรดดูการสาธิต Web Bluetooth ที่เราคัดสรรมาและCodelab อย่างเป็นทางการของ Web Bluetooth ด้วย

ห้องสมุด

  • web-bluetooth-utils เป็นโมดูล npm ที่เพิ่มฟังก์ชันอำนวยความสะดวกบางอย่างลงใน API
  • Shim ของ Web Bluetooth API พร้อมใช้งานใน noble ซึ่งเป็นโมดูลส่วนกลาง BLE ของ Node.js ที่ได้รับความนิยมมากที่สุด ซึ่งช่วยให้คุณใช้ webpack/browserify noble ได้โดยไม่ต้องมีเซิร์ฟเวอร์ WebSocket หรือปลั๊กอินอื่นๆ
  • angular-web-bluetooth เป็นโมดูลสำหรับ Angular ที่จะซ่อน บอยเลอร์เพลตทั้งหมดที่จำเป็นในการกำหนดค่า Web Bluetooth API

เครื่องมือ

  • เริ่มต้นใช้งาน Web Bluetooth เป็นเว็บแอปที่ใช้งานง่ายซึ่งจะสร้างโค้ดบอยเลอร์เพลต JavaScript ทั้งหมดเพื่อเริ่มโต้ตอบกับอุปกรณ์บลูทูธ ป้อนชื่ออุปกรณ์ บริการ ลักษณะ กำหนดคุณสมบัติ แล้ว คุณก็พร้อมใช้งาน
  • หากคุณเป็นนักพัฒนาแอปบลูทูธอยู่แล้ว ปลั๊กอิน Web Bluetooth Developer Studio จะสร้างโค้ด JavaScript ของ Web Bluetooth สำหรับอุปกรณ์บลูทูธด้วย

เคล็ดลับ

หน้าข้อมูลภายในของบลูทูธพร้อมใช้งานใน Chrome ที่ about://bluetooth-internals เพื่อให้คุณตรวจสอบทุกอย่างเกี่ยวกับอุปกรณ์บลูทูธที่อยู่ใกล้เคียงได้ ไม่ว่าจะเป็นสถานะ บริการ ลักษณะ และตัวอธิบาย

ภาพหน้าจอของหน้าภายในเพื่อแก้ไขข้อบกพร่องของบลูทูธใน Chrome
หน้าภายในใน Chrome สำหรับการแก้ไขข้อบกพร่องของอุปกรณ์บลูทูธ

นอกจากนี้ เราขอแนะนำให้คุณดูหน้าวิธีรายงานข้อบกพร่องของ Web Bluetooth อย่างเป็นทางการด้วย เนื่องจากบางครั้งการแก้ไขข้อบกพร่องของบลูทูธอาจเป็นเรื่องยาก

ขั้นตอนถัดไป

โปรดตรวจสอบสถานะการติดตั้งใช้งานเบราว์เซอร์และแพลตฟอร์มก่อนเพื่อดูว่าส่วนใดของ Web Bluetooth API ที่กำลังมีการติดตั้งใช้งาน

แม้ว่าฟีเจอร์นี้จะยังไม่สมบูรณ์ แต่เราจะให้คุณได้เห็นตัวอย่างสิ่งที่คาดว่าจะเกิดขึ้นในอนาคตอันใกล้

  • การสแกนหาโฆษณา BLE ที่อยู่ใกล้เคียง จะเกิดขึ้นกับ navigator.bluetooth.requestLEScan()
  • serviceadded เหตุการณ์ใหม่จะติดตามบริการ GATT ของบลูทูธที่ค้นพบใหม่ ขณะที่เหตุการณ์ serviceremoved จะติดตามบริการที่นำออก servicechanged เหตุการณ์ใหม่จะเริ่มทำงานเมื่อมีการเพิ่มหรือนำลักษณะและ/หรือตัวอธิบายออกจากบริการ GATT ของบลูทูธ

แสดงการสนับสนุน API

คุณวางแผนที่จะใช้ Web Bluetooth API หรือไม่ การสนับสนุนแบบสาธารณะของคุณช่วยให้ทีม Chrome จัดลําดับความสําคัญของฟีเจอร์และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นๆ เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้มีความสําคัญเพียงใด

ทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก #WebBluetooth และแจ้งให้เราทราบว่าคุณใช้ฟีเจอร์นี้ที่ใดและอย่างไร

แหล่งข้อมูล

คำขอบคุณ

ขอขอบคุณ Kayce Basques ที่ตรวจสอบ