Start · Sprachen · JavaScript · Referenz · BluetoothRemoteGATTServer.connect()

BluetoothRemoteGATTServer.connect()

Methode

Stellt eine GATT-Verbindung zum Bluetooth-Low-Energy-Gerät <code>this.device</code> her und liefert ein Promise, das mit dem verbundenen <code>BluetoothRemoteGATTServer</code> erfüllt wird.

seit JavaScript Experimentell: Chrome/Edge 56+, Opera; nicht in Fi Kategorie: webapi

Signatur

BluetoothRemoteGATTServer.prototype.connect()

Beschreibung

connect() baut eine Verbindung zum GATT-Server (Generic Attribute Profile) eines Bluetooth-Low-Energy-Geräts auf. Das Gerät muss vorher über navigator.bluetooth.requestDevice() ausgewählt worden sein. Man erreicht den Server über device.gatt. Erst wenn die Verbindung steht, kann man primäre Dienste (getPrimaryService()), Characteristics und Descriptors lesen, schreiben oder abonnieren.

Die Methode gibt ein Promise zurück. Es wird mit demselben BluetoothRemoteGATTServer-Objekt erfüllt, sobald die Verbindung aufgebaut ist. Danach ist server.connected gleich true. Besteht schon eine Verbindung, wird das Promise sofort erfüllt. Rufen mehrere Stellen im Skript connect() auf, zählt der Browser die Verbindung nur einmal. Ein einziges disconnect() trennt sie für alle.

Typische Einsatzfälle sind Fitness-Sensoren (Herzfrequenz), Smart-Home-Geräte, Mikrocontroller wie ESP32 oder micro:bit und medizinische Messgeräte. BLE-Verbindungen sind oft instabil. Man sollte daher auf das Event gattserverdisconnected am BluetoothDevice hören und bei Bedarf mit Backoff neu verbinden.

Rückgabewert

Typ
Promise<BluetoothRemoteGATTServer>
Beschreibung
Ein Promise, das mit dem verbundenen BluetoothRemoteGATTServer erfüllt wird. Es wird mit einer DOMException abgelehnt, zum Beispiel NetworkError, wenn das Gerät nicht erreichbar ist oder die Verbindung abbricht, oder SecurityError. Ein AbortError tritt auf, wenn während des Aufbaus disconnect() aufgerufen wird.

Beispiele

Herzfrequenz-Sensor verbinden und Wert abonnieren

// Muss durch eine Nutzeraktion ausgelöst werden (z. B. Klick)
document.querySelector('#verbinden').addEventListener('click', async () => {
  try {
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['heart_rate'] }]
    });

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

    const service = await server.getPrimaryService('heart_rate');
    const characteristic = await service.getCharacteristic('heart_rate_measurement');

    characteristic.addEventListener('characteristicvaluechanged', (event) => {
      const value = event.target.value;
      const flags = value.getUint8(0);
      // Bit 0 gibt an, ob der Wert 8 oder 16 Bit breit ist
      const bpm = flags & 0x01 ? value.getUint16(1, true) : value.getUint8(1);
      console.log(`Puls: ${bpm} bpm`);
    });

    await characteristic.startNotifications();
  } catch (error) {
    console.error(`Fehler: ${error.name} – ${error.message}`);
  }
});
Verbunden: true Puls: 72 bpm Puls: 74 bpm

Batteriestand einmalig lesen und Verbindung trennen

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

  const server = await device.gatt.connect();
  try {
    const service = await server.getPrimaryService('battery_service');
    const level = await service.getCharacteristic('battery_level');
    const value = await level.readValue();
    console.log(`Batterie: ${value.getUint8(0)} %`);
  } finally {
    // Verbindung immer sauber freigeben
    server.disconnect();
  }
};

document.querySelector('#batterie').addEventListener('click', leseBatterie);
Batterie: 87 %

Automatisch neu verbinden mit exponentiellem Backoff

const verbindeMitRetry = async (device, maxVersuche = 5) => {
  for (let versuch = 0; versuch < maxVersuche; versuch++) {
    try {
      const server = await device.gatt.connect();
      console.log(`Verbunden nach ${versuch + 1} Versuch(en)`);
      return server;
    } catch (error) {
      const wartezeit = 2 ** versuch * 500;
      console.warn(`${error.name}: neuer Versuch in ${wartezeit} ms`);
      await new Promise((resolve) => setTimeout(resolve, wartezeit));
    }
  }
  throw new Error('Verbindung fehlgeschlagen');
};

document.querySelector('#start').addEventListener('click', async () => {
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ namePrefix: 'ESP32' }]
  });

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

  await verbindeMitRetry(device);
});
Verbunden nach 1 Versuch(en) Verbindung verloren – verbinde neu … NetworkError: neuer Versuch in 500 ms Verbunden nach 2 Versuch(en)

// Wichtig · Fallstricke

  • Browser-Unterstützung: Web Bluetooth ist experimentell und nur in Chromium-Browsern verfügbar (Chrome, Edge, Opera, auch Chrome für Android). Firefox und Safari unterstützen es nicht, auch nicht Safari auf iOS. Unter Linux muss es teils per Flag aktiviert werden. Vorher mit 'bluetooth' in navigator prüfen, ob die API vorhanden ist.
  • Sicherer Kontext: Die API funktioniert nur über HTTPS oder localhost. requestDevice() braucht eine Nutzeraktion, etwa einen Klick. connect() selbst braucht keine. In Iframes muss die Permissions Policy bluetooth erlaubt sein.
  • Zugriff auf Dienste: Nur Dienste, die in filters oder optionalServices von requestDevice() stehen, sind nach dem Verbinden erreichbar. Alle anderen führen zu einem SecurityError.
  • Instabile Verbindungen: connect() kann mit NetworkError fehlschlagen, auch wenn das Gerät in Reichweite ist. Manche Geräte erlauben nur eine Verbindung gleichzeitig, sodass etwa eine offene Smartphone-App den Zugang blockiert. Deshalb Wiederholungsversuche einbauen und gattserverdisconnected behandeln.
  • Kein eingebauter Timeout: Das Promise kann lange offen bleiben. Bei Bedarf eine eigene Zeitgrenze mit Promise.race() setzen und anschließend disconnect() aufrufen. Dadurch wird das ausstehende Promise mit AbortError abgelehnt.
  • Verbindungen nicht offen lassen. Mit disconnect() freigeben, wenn sie nicht mehr gebraucht werden. Das schont den Akku des Geräts.