웹에서 블루투스를 통해 직렬

프랑수아 보포르
프랑수아 보포르

Web Bluetooth APIWeb Serial API는 웹 앱이 저전력 블루투스 (BLE) 기기와 직렬 기기와 각각 통신할 수 있게 해줍니다. 많은 웹 개발자가 이미 이러한 API를 사용하여 큰 성공을 거두고 있지만 Bluetooth 클래식 기기에 대한 지원에 대한 수요도 증가하고 있습니다.

이제 Web Serial API는 데스크톱 Chrome 117의 직렬 포트 프로필 (SPP)을 포함하여 페어링된 블루투스 기본 기기에서 RFCOMM 서비스와의 통신을 지원합니다. 이는 웹 개발자와 사용자 모두에게 새로운 가능성을 열어줍니다. 이러한 기능을 활용할 수 있는 몇 가지 실제 기기는 다음과 같습니다.

  • Pixel Buds Pro 및 기타 무선 이어폰은 RFCOMM을 사용하여 오디오 설정 및 펌웨어 업데이트를 관리합니다.
  • 모바일 POS 시스템은 블루투스 SPP를 사용하여 영수증 프린터와 통신합니다.
  • 가축 RFID 태그 리더는 블루투스 SPP를 사용하여 동물의 이동을 기록합니다.

블루투스 RFCOMM 프로토콜

90년대 후반으로 돌아가 보세요. Palm Pilot을 크래들에 넣기만 하면 다음 날 캘린더를 동기화할 수 있습니다. 아니면 무선으로 가능하지 않을까요? 새로운 "Bluetooth" 기술을 사용하면 복잡한 코드를 없앨 수 있습니다. 무선의 미래! 한 가지 문제가 있습니다. 존재하는 모든 것은 RS-232 케이블로 연결되도록 설계되어 있습니다. 따라서 블루투스는 무선 주파수 통신 (RFCOMM) 프로토콜을 사용하여 이 인터페이스를 모든 기존 소프트웨어 및 하드웨어에 제공합니다.

오늘날에도 RFCOMM 서비스는 신규 및 기존 하드웨어에서 널리 사용되고 있습니다. 지금까지 저전력 블루투스로는 충족되지 않았던 특정 지연 시간과 대역폭 요구사항을 충족할 수 있게 해줍니다. 그래서 제조업체가 결국 저전력 블루투스로 이전하고 개발자는 대신 Web Bluetooth API를 사용할 수 있게 되기 전에 기존 RFCOMM 서비스에 액세스할 수 있도록 직렬 기기 연결을 위한 API인 Web Serial과 블루투스 간의 통합을 개발했습니다.

Web Serial API 변경사항

데스크톱의 Chrome 117부터 웹 개발자는 이제 Web Serial API를 사용하는 RFCOMM 서비스를 통해 페어링된 Bluetooth Classic 기기와 안정적으로 통신할 수 있습니다. 이는 Web Serial API의 다음과 같은 업데이트 덕분에 가능했습니다.

  • 이제 Chrome에서 표준화된 블루투스 클래식 직렬 포트 프로필을 사용하여 직렬 인터페이스를 노출하는 페어링된 블루투스 기기를 열거합니다.
  • 이제 운영체제에서 에뮬레이션된 직렬 포트를 통해 기기 노드를 만들지 않은 경우에도 Chrome이 직렬 인터페이스와 통신할 수 있습니다.
  • 이제 Chrome에서 RFCOMM 직렬 인터페이스를 노출하는 비직렬 포트 서비스와 통신할 수 있습니다 (비표준 서비스 클래스 ID 참고).

직렬 포트 읽기 및 쓰기 도움말에서 Web Serial API 사용 방법을 알아보세요. 이 도움말에서는 블루투스에 대한 기본 지식이 있다고 가정하고 블루투스를 통한 직렬 변경사항에 중점을 둡니다.

사용자는 필터를 지정하지 않고 navigator.serial.requestPort()를 호출하여 블루투스가 아닌 직렬 포트, 이미 매핑된 블루투스 직렬 포트, 표준화된 블루투스 클래식 직렬 포트 프로필에서 제공하는 매핑되지 않은 모든 직렬 포트를 선택할 수 있습니다.

// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();

대부분의 기기는 표준화된 블루투스 클래식 직렬 포트 프로필을 통해 SPP 기반 통신을 노출하지만 일부 기기는 맞춤 RFCOMM 기반 서비스를 사용합니다. 기기의 서비스 클래스 ID가 표준 블루투스 UUID 범위에 속하지 않습니다.

아래 예와 같이 이러한 맞춤 RFCOMM 기반 서비스에 액세스하려면 allowedBluetoothServiceClassIds 목록을 navigator.serial.requestPort()에 전달해야 합니다.

const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";

// Prompt user to select any serial port.
// Access to the custom Bluetooth RFCOMM service above will be allowed.
const port = await navigator.serial.requestPort({
  allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
});

블루투스 SIG 기본 UUID(즉, '-0000-1000-8000-00805f9b34fb')를 사용하는 모든 서비스 클래스 ID(즉, '-0000-1000-8000-00805f9b34fb')는 직렬 포트 프로필 ID를 제외하고 차단됩니다. Chrome은 오디오 및 동영상 등의 블루투스 클래식 서비스를 지원하지 않기 때문입니다.

또한 navigator.serial.requestPort() 호출 시 bluetoothServiceClassId 필터 키를 사용하여 서비스 클래스 ID로 식별된 필터링된 블루투스 직렬 포트 목록을 사용자에게 표시할 수도 있습니다. 아래 예를 참조하세요.

const myBluetoothServiceUuid = "01234567-89ab-cdef-0123-456789abcdef";

// Prompt the user to select Bluetooth serial ports with
// the custom Bluetooth RFCOMM service above.
const port = await navigator.serial.requestPort({
  allowedBluetoothServiceClassIds: [myBluetoothServiceUuid],
  filters: [{ bluetoothServiceClassId: myBluetoothServiceUuid }],
});

직렬 포트가 블루투스 기기의 일부인 경우 포트가 연결된 RFCOMM 채널과 연결된 서비스 클래스 ID가 포함된 새 bluetoothServiceClassId 키는 port.getInfo()를 호출하여 반환된 직렬 포트 정보에서 사용할 수 있습니다. 직렬 포트가 매핑되면 '00001101-0000-1000-8000-00805f9b34fb' 또는 0x1101을 짧은 형식으로 반환합니다.

const { bluetoothServiceClassId } = port.getInfo();

사용 사례 예시: Pixel Buds Pro 제어

Pixel Buds Pro 웹 호환 앱은 사용자가 웹브라우저가 있는 모든 기기에서 Pixel Buds Pro를 제어할 수 있도록 하는 새로운 웹 앱입니다. 인스턴트 로드 환경을 위해 프로그레시브 웹 앱 기술을 사용하여 제작되며 선택적으로 다른 운영체제 앱과 함께 설치할 수 있습니다.

앱이 Web Serial API를 사용하여 Pixel Buds Pro와 통신합니다. 이를 통해 사용자는 액티브 노이즈 제어, 이퀄라이저, 인이어 감지, 펌웨어 업데이트 등 Pixel Buds Pro의 다양한 설정을 제어할 수 있습니다.

Pixel Buds Pro 웹 호환 앱을 사용해 보려면 ChromeOS 기기에서 mypixelbuds.google.com을 방문하세요 (다른 플랫폼도 곧 지원 예정).

Pixel Buds Pro 웹 호환 앱의 스크린샷
Pixel Buds Pro 웹 호환 앱

자료

감사의 말

리뷰를 작성해 주신 라일리 그랜트, 토마스 스타이너, 벤 모스, 빈센트 쉐이브님께 감사드립니다. UnsplashMika Baumeister의 히어로 이미지입니다.