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);
        });
      }

      see also