demo · v130
reconnect policy decision tree
The chromestatus motivation by name: "the application should avoid re-opening the port in order to prevent reconnecting to the device" when the user intentionally disconnected it. Walk a real Bluetooth serial peripheral (a label printer / cash drawer / Arduino over BT-SPP) through six scenarios and see what the right reconnect policy is for each, given the new connected attribute and the connect/disconnect events.
pick a scenario
decision tree
pre-Chrome 130 (no signal)
Chrome 130+ (with connected + events)
the code
// On port acquisition, register the connect/disconnect handlers
// and inspect the boolean .connected attribute.
async function adoptPort(port) {
// Open if logically connected — wired or wireless-but-paired.
if (port.connected) await port.open({ baudRate: 9600 });
port.addEventListener("connect", async () => {
// BT device came back into range. We never closed the port from JS,
// so respect the user's earlier intent by re-opening only if they
// hadn't explicitly disconnected via system UI.
if (userIntentionallyDisconnected.has(port)) return;
try {
await port.open({ baudRate: 9600 });
} catch (e) { console.log("reopen failed:", e.message); }
});
port.addEventListener("disconnect", () => {
// Range loss vs system-disconnect both raise this. The connected
// attribute is now false either way; the difference shows up via
// the next connect: if it fires within ~30s we treat it as range
// recovery and re-open. If the user pressed "Forget" or system
// disconnected, we never see another connect.
scheduleReconnectGuard(port);
});
}