Start · Sprachen · JavaScript · Referenz · BluetoothRemoteGATTServer

BluetoothRemoteGATTServer

Schnittstelle

Stellt den GATT-Server eines entfernten Bluetooth-Low-Energy-Geräts dar. Über ihn baut man die Verbindung auf, trennt sie und fragt primäre Dienste ab.

seit JavaScript Chromium-Browser (Chrome/Edge/Opera 56+), nur sich Kategorie: webapi

Signatur

interface BluetoothRemoteGATTServer

Beschreibung

BluetoothRemoteGATTServer gehört zur Web Bluetooth API und steht für den GATT-Server (Generic Attribute Profile) auf einem entfernten BLE-Gerät. Einen eigenen Konstruktor gibt es nicht. Die Instanz bekommt man über die Eigenschaft BluetoothDevice.gatt, nachdem der Nutzer über navigator.bluetooth.requestDevice() ein Gerät ausgewählt hat.

Das Interface ist der Einstieg in die Hierarchie Dienste → Charakteristiken → Deskriptoren:

  • device (schreibgeschützt): Verweis auf das zugehörige BluetoothDevice.
  • connected (schreibgeschützt): true, solange das Skript mit dem Gerät verbunden ist.
  • connect(): Baut die Verbindung auf. Gibt ein Promise<BluetoothRemoteGATTServer> zurück.
  • disconnect(): Trennt die Verbindung sofort (synchron, ohne Rückgabewert).
  • getPrimaryService(service): Liefert ein Promise<BluetoothRemoteGATTService> für eine bestimmte Dienst-UUID.
  • getPrimaryServices(service?): Liefert ein Promise<BluetoothRemoteGATTService[]> mit allen erlaubten primären Diensten, auf Wunsch nach UUID gefiltert.

Das Interface wird zum Beispiel für Fitness-Tracker, Herzfrequenzsensoren, Mikrocontroller wie ESP32 oder Arduino, smarte Lampen und Messgeräte genutzt, also überall dort, wo eine Webanwendung ohne native App direkt mit BLE-Hardware sprechen soll. Welche Dienste zugänglich sind, legen die beim requestDevice()-Aufruf angegebenen filters und optionalServices fest.

Parameter

Name Typ Default Beschreibung
$service string | number Parameter von getPrimaryService() (dort Pflicht) und getPrimaryServices() (dort optional). Mögliche Werte: vollständige 128-Bit-UUID, 16/32-Bit-Alias als Zahl (z. B. 0x180D) oder ein standardisierter Name wie 'heart_rate' oder 'battery_service'.

Rückgabewert

Typ
BluetoothRemoteGATTServer
Beschreibung
Wird über BluetoothDevice.gatt bereitgestellt. connect() löst mit derselben Server-Instanz auf, die getPrimaryService*-Methoden mit BluetoothRemoteGATTService-Objekten.

Beispiele

Verbinden und Akkustand auslesen

const button = document.querySelector('#connect');

button.addEventListener('click', async () => {
  try {
    // requestDevice muss durch eine Nutzeraktion ausgelöst werden
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['battery_service'] }]
    });

    const server = await device.gatt.connect();
    console.log('Verbunden:', server.connected);

    const service = await server.getPrimaryService('battery_service');
    const characteristic = await service.getCharacteristic('battery_level');
    const value = await characteristic.readValue();

    console.log(`Akkustand: ${value.getUint8(0)} %`);
    server.disconnect();
  } catch (err) {
    console.error('Bluetooth-Fehler:', err.name, err.message);
  }
});
Verbunden: true Akkustand: 87 %

Alle erlaubten primären Dienste auflisten

const listServices = async () => {
  const device = await navigator.bluetooth.requestDevice({
    acceptAllDevices: true,
    optionalServices: ['heart_rate', 'battery_service', 'device_information']
  });

  const server = await device.gatt.connect();
  const services = await server.getPrimaryServices();

  for (const service of services) {
    console.log('Dienst:', service.uuid);
  }
  return services.length;
};

document.querySelector('#scan').addEventListener('click', listServices);
Dienst: 0000180d-0000-1000-8000-00805f9b34fb Dienst: 0000180f-0000-1000-8000-00805f9b34fb

Verbindungsabbruch erkennen und automatisch neu verbinden

const connectWithRetry = async (device, attempts = 3) => {
  for (let i = 1; i <= attempts; i++) {
    try {
      const server = await device.gatt.connect();
      console.log(`Verbunden (Versuch ${i})`);
      return server;
    } catch (err) {
      console.warn(`Versuch ${i} fehlgeschlagen:`, err.message);
      // exponentielles Backoff: 1 s, 2 s, 4 s ...
      await new Promise((r) => setTimeout(r, 2 ** (i - 1) * 1000));
    }
  }
  throw new Error('Verbindung nicht möglich');
};

const start = async () => {
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ services: ['heart_rate'] }]
  });

  device.addEventListener('gattserverdisconnected', () => {
    console.log('Verbindung verloren – verbinde neu …');
    connectWithRetry(device);
  });

  await connectWithRetry(device);
};

document.querySelector('#start').addEventListener('click', start);
Verbunden (Versuch 1) Verbindung verloren – verbinde neu … Verbunden (Versuch 1)

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur Chromium-basierte Browser (Chrome, Edge, Opera, teils Android). Firefox und Safari (auch auf iOS) unterstützen Web Bluetooth nicht. Unter Linux ist die API teilweise nur per Flag verfügbar. Vor der Nutzung mit 'bluetooth' in navigator prüfen.
  • Sicherer Kontext und Nutzeraktion: Die API funktioniert nur über HTTPS oder localhost. requestDevice() muss von einer Nutzeraktion wie einem Klick ausgelöst werden. In Iframes braucht es die Permissions-Policy bluetooth.
  • Dienstzugriff: getPrimaryService() schlägt mit SecurityError fehl, wenn die UUID weder in filters noch in optionalServices angegeben wurde. Existiert der Dienst nicht, kommt ein NotFoundError.
  • Verbindungsstatus: Ist das Gerät getrennt, lösen die getPrimaryService*-Methoden einen NetworkError aus. Deshalb vorher connected prüfen oder das Event gattserverdisconnected am BluetoothDevice abonnieren (per addEventListener oder ongattserverdisconnected).
  • disconnect() gibt kein Promise zurück und löst das Event gattserverdisconnected aus. Wer im Handler automatisch neu verbindet, sollte ein Flag setzen, damit ein gewolltes Trennen keine neue Verbindung anstößt.
  • Datenschutz: Manche UUIDs, etwa bestimmte HID-Dienste, stehen auf einer Sperrliste und sind grundsätzlich nicht erreichbar.