Назад в Центр знаний
Платформа

Разрешения Web Serial и жизненный цикл порта

Запрашивайте Web Serial действием пользователя, отделяйте разрешение от готовности порта, ограничивайте потоки и сохраняйте запасной путь.

BotBrowser Team

Документация

Нужна структурированная документация по теме Платформа?

Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.

Web Serial позволяет запросить выбранный пользователем последовательный порт, но результат селектора не доказывает соединение, доверие или владение. BotBrowser может проверить ветки разрешения и запасного пути страницы в управляемом контексте; он не предоставляет физическое устройство, не выдаёт системное разрешение и не доказывает аппаратный ввод-вывод. Запрашивайте после действия, открывайте поддержанный порт, ограничивайте кадры, отменяйте потоки при отключении и сохраняйте задачу без оборудования.

Действие пользователя, разрешение Web Serial, открытый SerialPort, ограниченные потоки, очистка отключения и запасной путь

TL;DR

  • navigator.serial.requestPort({ filters: [{ usbVendorId: 0x2341 }] }) требует защищённый контекст и краткую активацию пользователя.
  • Выбранный SerialPort является возможностью источника, но не доказывает, что порт открыт, подключён или совместим.
  • Открывайте port.open({ baudRate: 115200 }) с проверенной конфигурацией и валидируйте каждый кадр.
  • События connect и disconnect показывают наблюдение браузера; отменяйте readers, освобождайте locks и закрывайте порт.
  • Храните granted, unsupported, invalid-frame или disconnected, а не серийные номера и сырые буферы.

Содержание

Запрашивайте в момент использования

Web Serial работает только в защищённых контекстах, а requestPort() должен следовать действию. Наличие navigator.serial не открывает селектор. Политика iframe, настройка браузера, платформа или ОС могут отклонить запрос.

async function connectSerial() {
  if (!window.isSecureContext || !navigator.serial) return showSerialState('unsupported');
  setSerialState('requesting');
  try {
    const port = await navigator.serial.requestPort({
      filters: [{ usbVendorId: 0x2341 }],
    });
    await openSelectedPort(port);
  } catch (error) {
    showSerialState(error.name === 'NotFoundError' ? 'cancelled' : 'denied');
  }
}

connectButton.addEventListener('click', connectSerial);

Не открывайте селектор при загрузке и не повторяйте запрос после отмены. Сохраните черновик. Доступ WebUSB: разрешения, интерфейсы и приватность разделяет разрешение и готовность; Разрешения WebHID и приватность устройств рассматривает жизненный цикл HID-отчётов; Отпечаток разрешений браузера объясняет, почему состояние не выдаёт доступ и не определяет человека.

Отделяйте разрешение от готовности

requestPort() возвращает выбранный порт, но он может быть отключён, иметь неверный baudRate или другой протокол. Считайте выбор, открытие, чтение, запись и закрытие отдельными состояниями. Документируйте baudRate, dataBits, stopBits, parity и flowControl, а проверку протокола выполняйте после декодера.

navigator.serial.getPorts() не является полным инвентарём. Повторное подключение должно быть явным и снова проверять конфигурацию. Спецификация Web Serial и MDN Web Serial API описывают интерфейс, но не доказывают личность, место или физический результат.

Ограничивайте потоки

port.readable и port.writable являются асинхронными потоками. Используйте максимум размера, разделитель или длину, checksum при наличии в протоколе и тайм-аут неполного кадра.

const MAX_FRAME_BYTES = 128;

async function readSerialFrames(port) {
  const reader = port.readable.getReader();
  try {
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      if (value.byteLength > MAX_FRAME_BYTES) {
        showSerialState('invalid-frame');
        continue;
      }
      acceptBoundedFrame(value);
    }
  } finally {
    reader.releaseLock();
  }
}

Не записывайте каждый байт и не передавайте произвольный кадр интерпретатору. Классифицируйте invalid-length, invalid-checksum и timeout. Успешный writer.write() означает только принятие браузером, а не движение устройства. Освобождайте writer и отменяйте reader до close().

Согласуйте connect и disconnect

connect показывает появление порта, а disconnect означает наблюдаемое удаление. Они не объясняют причину и не разрешают тихий запрос. При отключении сделайте задачу терминальной, отмените reader, освободите writer, вызовите port.close() с обработкой ошибки, удалите listeners, сохраните данные и покажите кнопку переподключения. Не отправляйте последнюю команду автоматически.

Используйте idle, requesting, selected, opening, opened, reading, invalid-frame, disconnected, cancelled и fallback. При возврате портов повторяйте конфигурацию и handshake; serialNumber и getInfo() не являются личностью.

Минимизируйте метаданные и сохраняйте запасной путь

Разделяйте разрешение, сессию, согласие протокола и удалённую загрузку. Локальное чтение не разрешает передачу. В журнале достаточно unsupported, denied, cancelled, opened, invalid-frame, disconnected или fallback, времени и окружения. Не храните getInfo(), USB-идентификаторы, буферы и длинную историю. Оставьте ручной ввод, импорт, симулированное значение или статическую конфигурацию.

Классифицируйте результаты

СтадияЧто установленоБезопасное действие
API отсутствует, контекст небезопасен или политикаWeb Serial не запускаетсяСохранить задачу без порта
Селектор отменён или разрешение отклоненоНет доступа для попыткиСохранить черновик
open() отклонёнСессия непригоднаПоказать настройки и закрыть
Неверный кадрПротокол отклонил входОтбросить и классифицировать
disconnectБраузер наблюдал удалениеОтменить, закрыть, сохранить и предложить повтор
Валидный кадрПринято одно значениеНе выводить физический эффект

Возможность и ограничение BotBrowser

BotBrowser может проверить кнопку, обнаружение, результат селектора, ограниченную валидацию, очистку отключения и запасной путь. Документация расширенных возможностей описывает такой контекст. Он не предоставляет периферийное устройство, системное разрешение, гарантированный порт или доказательство аппаратного эффекта. BotBrowser проверяет видимые состояния navigator.serial и запасной путь, но не подтверждает работу реального электрического устройства.

const serialOutcome = { state: 'fallback', rawIdentifiersRetained: false };
showSerialState(serialOutcome.state);
{
  "api": "navigator.serial",
  "permission": "denied",
  "portState": "fallback",
  "framesAccepted": 0,
  "rawIdentifiersRetained": false,
  "physicalDevice": "not-asserted"
}

Источники

Итог

Используйте явное действие, разделяйте разрешение, открытие и потоки, проверяйте каждый кадр и отменяйте readers перед закрытием. Сохраняйте задачу без оборудования и записывайте стадию ошибки вместо метаданных. Повторяйте fixture после обновления; успех страницы не обещает физического поведения.

#Web Serial API#Разрешения#Последовательные Порты#Приватность#BotBrowser

Эта статья входит в руководство: Поверхности веб-платформы: карта проверки

Переведите BotBrowser из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.