Signatur
Beschreibung
Mit close() beenden Sie die Verbindung zu einem seriellen Gerät (z. B. Arduino, Mikrocontroller, GPS-Empfänger oder Barcode-Scanner), die Sie vorher mit SerialPort.open() geöffnet haben. Der Browser gibt dabei den Port für das Betriebssystem frei. Danach können andere Anwendungen oder ein neuer Aufruf von open() den Port wieder verwenden.
Wichtig ist die Reihenfolge: close() funktioniert nur, wenn weder port.readable noch port.writable gesperrt sind. Hält ein ReadableStreamDefaultReader oder WritableStreamDefaultWriter die Sperre, wird das Promise abgelehnt. Brechen Sie deshalb zuerst laufende Lesevorgänge mit reader.cancel() ab, rufen Sie releaseLock() auf Reader und Writer auf und warten Sie auf Pipes (pipeTo()). Erst dann schließen Sie den Port.
Beim Schließen werden gepufferte, noch nicht gesendete Daten verworfen. Warten Sie also auf writer.close() bzw. auf ausstehende write()-Promises, wenn alle Daten ankommen müssen. Nach dem Schließen sind port.readable und port.writable wieder null.
Rückgabewert
Promise, das mit undefined erfüllt wird, sobald der Port geschlossen ist. Es wird abgelehnt, wenn der Port nicht geöffnet ist (InvalidStateError) oder wenn readable/writable noch durch einen Reader oder Writer gesperrt sind (TypeError).Beispiele
Port öffnen, Befehl senden und wieder schließen
const sendCommand = async () => {
// Muss durch eine Benutzeraktion ausgelöst werden (z. B. Klick)
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
const writer = port.writable.getWriter();
await writer.write(new TextEncoder().encode('LED ON\n'));
writer.releaseLock(); // Sperre freigeben, sonst schlägt close() fehl
await port.close();
console.log('Port geschlossen, writable =', port.writable);
};
document.querySelector('#send').addEventListener('click', sendCommand);
Laufende Leseschleife sauber beenden
let port;
let reader;
let keepReading = true;
const readLoop = async () => {
while (port.readable && keepReading) {
reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break; // durch reader.cancel() ausgelöst
console.log('Empfangen:', value.length, 'Bytes');
}
} catch (err) {
console.error('Lesefehler:', err);
} finally {
reader.releaseLock();
}
}
await port.close();
console.log('Port geschlossen');
};
document.querySelector('#connect').addEventListener('click', async () => {
port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
readLoop();
});
document.querySelector('#disconnect').addEventListener('click', async () => {
keepReading = false;
await reader?.cancel(); // beendet das ausstehende read()
});
Schließen bei Verwendung von TextDecoderStream/pipeTo
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
const decoder = new TextDecoderStream();
const readableClosed = port.readable.pipeTo(decoder.writable);
const reader = decoder.readable.getReader();
// ... später: Verbindung trennen
const disconnect = async () => {
await reader.cancel();
// Die Pipe wird durch das Abbrechen abgelehnt – das ist erwartet
await readableClosed.catch(() => {});
await port.close();
console.log('Verbindung getrennt');
};
await disconnect();
// Wichtig · Fallstricke
- Häufigster Fehler:
TypeError: Failed to execute 'close' on 'SerialPort': Cannot cancel a locked stream. Das bedeutet, dass ein Reader oder Writer noch aktiv ist. Rufen Sie vorherreader.cancel()undreleaseLock()auf und warten Sie auf Pipes vonpipeTo(). - Ein Aufruf von
close()auf einem Port, der nicht geöffnet ist, lehnt das Promise mitInvalidStateErrorab. Prüfen Sie z. B. mitport.readable !== null, ob der Port offen ist. - Daten, die noch nicht gesendet wurden, gehen verloren. Warten Sie deshalb auf ausstehende
writer.write()- bzw.writer.close()-Promises. - Wird das Gerät physisch getrennt, löst der Browser das Ereignis
disconnectaus und schließt den Port selbst. Ein anschließender Aufruf vonclose()ist dann nicht mehr nötig. - Kompatibilität: Die Web Serial API gibt es nur in Chromium-basierten Desktop-Browsern (ab Chrome/Edge 89). Sie funktioniert nur in einem sicheren Kontext (HTTPS) und steht in Fenstern und Dedicated Workern zur Verfügung. Firefox und Safari unterstützen sie nicht. Prüfen Sie die Unterstützung mit
'serial' in navigator. - Über eine Permissions-Policy (
serial) kann die API z. B. in iframes gesperrt sein.