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

François Beaufort
François Beaufort

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

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

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

블루투스 RFCOMM 프로토콜

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

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

Web Serial API 변경사항

데스크톱의 Chrome 117부터 웹 개발자는 이제 Web Serial API를 사용하여 RFCOMM 서비스를 통해 페어링된 블루투스 클래식 기기와 안정적으로 통신할 수 있습니다. 이는 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],
});

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

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 웹 호환 앱

리소스

감사의 말

리뷰를 남겨 주신 라일리 그랜트, 토마스 슈타이너, 벤 모스, 빈센트 샤이브에게 감사의 인사를 전합니다. 히어로 이미지: 미카 바우메이스터(Unsplash)