Start · Sprachen · JavaScript · Referenz · USBDevice.releaseInterface()

USBDevice.releaseInterface()

Methode

Gibt ein zuvor mit <code>claimInterface()</code> beanspruchtes USB-Interface wieder frei und liefert ein Promise, das nach erfolgreicher Freigabe aufgelöst wird.

seit JavaScript Chrome/Edge 61+, Opera 48+ (nicht in Firefox und S Kategorie: webapi

Signatur

USBDevice.prototype.releaseInterface(interfaceNumber)

Beschreibung

Mit releaseInterface() hebt eine Seite den exklusiven Zugriff auf ein USB-Interface wieder auf, den sie vorher mit USBDevice.claimInterface() bekommen hat. Danach können andere Treiber, Tabs oder Anwendungen das Interface wieder nutzen. Transfers über die Endpunkte dieses Interfaces, also transferIn() und transferOut(), sind danach nicht mehr möglich.

Rufen Sie die Methode auf, sobald Sie die Kommunikation beenden, zum Beispiel vor USBDevice.close(), beim Trennen durch den Nutzer oder vor dem Wechsel der Konfiguration mit selectConfiguration(). Das Gerät muss dafür geöffnet sein (device.opened === true), und das Interface muss beansprucht sein (USBInterface.claimed === true).

Laufende Transfers auf dem Interface werden bei der Freigabe abgebrochen. Ihre Promises werden abgelehnt, meist mit einer AbortError-DOMException. Warten Sie deshalb am besten auf laufende Transfers oder brechen Sie sie bewusst ab, bevor Sie das Interface freigeben.

Parameter

Name Typ Default Beschreibung
$interfaceNumber Pflicht number Die Nummer des freizugebenden Interfaces (USBInterface.interfaceNumber) in der aktiven Konfiguration.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined aufgelöst wird, sobald das Interface freigegeben ist. Abgelehnt wird es z. B. mit InvalidStateError, wenn das Gerät nicht geöffnet ist, mit NotFoundError, wenn es die Interface-Nummer nicht gibt, oder mit NetworkError, wenn das Gerät getrennt wurde.

Beispiele

Interface nach der Kommunikation freigeben und Gerät schließen

const connectAndSend = async () => {
  // Muss durch eine Nutzeraktion (z. B. Klick) ausgelöst werden
  const device = await navigator.usb.requestDevice({
    filters: [{ vendorId: 0x2341 }]
  });

  await device.open();
  if (device.configuration === null) {
    await device.selectConfiguration(1);
  }
  await device.claimInterface(0);

  try {
    const data = new TextEncoder().encode('PING');
    const result = await device.transferOut(1, data);
    console.log('Gesendet:', result.bytesWritten, 'Bytes');
  } finally {
    // Interface immer freigeben, auch wenn ein Fehler auftritt
    await device.releaseInterface(0);
    await device.close();
    console.log('Interface freigegeben, Gerät geschlossen');
  }
};

document.querySelector('#connect').addEventListener('click', connectAndSend);
Gesendet: 4 Bytes Interface freigegeben, Gerät geschlossen

Alle beanspruchten Interfaces sicher freigeben

const releaseAll = async (device) => {
  if (!device.opened || !device.configuration) return;

  const claimed = device.configuration.interfaces
    .filter((iface) => iface.claimed);

  for (const iface of claimed) {
    try {
      await device.releaseInterface(iface.interfaceNumber);
      console.log(`Interface ${iface.interfaceNumber} freigegeben`);
    } catch (err) {
      console.warn(`Freigabe fehlgeschlagen (${iface.interfaceNumber}):`, err.name);
    }
  }
};

const [device] = await navigator.usb.getDevices();
if (device) await releaseAll(device);
Interface 0 freigegeben Interface 2 freigegeben

Aufräumen, wenn die Seite verlassen wird

let activeDevice = null;

const cleanup = async () => {
  if (activeDevice?.opened) {
    await activeDevice.releaseInterface(0).catch(() => {});
    await activeDevice.close().catch(() => {});
  }
};

// Wurde das Gerät abgesteckt, ist keine Freigabe mehr nötig
navigator.usb.addEventListener('disconnect', (event) => {
  if (event.device === activeDevice) {
    activeDevice = null;
    console.log('Gerät getrennt');
  }
});

window.addEventListener('pagehide', cleanup);

// Wichtig · Fallstricke

  • Browserunterstützung: WebUSB gibt es nur in Chromium-Browsern (Chrome, Edge, Opera) auf dem Desktop und in Chrome für Android. Firefox und Safari unterstützen WebUSB nicht. Prüfen Sie deshalb vorher mit 'usb' in navigator, ob die API vorhanden ist. Die API läuft nur in sicheren Kontexten (HTTPS) und lässt sich per Permissions-Policy usb sperren.
  • Laufende Transfers: Offene Promises von transferIn() und transferOut() auf dem Interface werden bei der Freigabe abgelehnt. Fangen Sie diese Fehler ab.
  • Reihenfolge: Geben Sie Interfaces frei, bevor Sie close() oder selectConfiguration() aufrufen. Zwar gibt close() beanspruchte Interfaces implizit frei, eine ausdrückliche Freigabe macht den Code aber klarer.
  • Getrennte Geräte: Ist das Gerät bereits abgesteckt, wird das Promise abgelehnt. Behandeln Sie beim Aufräumen Fehler deshalb tolerant.
  • Ein nicht freigegebenes Interface bleibt blockiert, bis Tab oder Gerät geschlossen werden. Andere Anwendungen können so lange nicht darauf zugreifen.