일반적이지 않은 HID 기기에 연결

WebHID API를 사용하면 웹사이트에서 대체 보조 키보드와 독특한 게임패드에 액세스할 수 있습니다.

François Beaufort
François Beaufort

인간 인터페이스 장치 (HID)에는 너무 새롭거나 너무 오래되었거나 특이한 디자인의 키보드 또는 특이한 게임패드 액세스할 수 있도록 하려면 장치 드라이버입니다. WebHID API는 을 사용하여 JavaScript에서 기기별 로직을 구현할 수 있습니다.

추천 사용 사례

HID 기기는 인간으로부터 입력을 받거나 인간에게 출력을 제공합니다. 기기 예 키보드, 포인팅 기기 (마우스, 터치스크린 등), 게임패드가 포함됩니다. HID 프로토콜을 사용하면 데스크톱에서 이러한 기기에 액세스할 수 있습니다. 운영 체제 드라이버를 사용하는 컴퓨터에서 작업할 수 있습니다. 웹 플랫폼이 HID 기기 지원 이러한 요인을 활용할 수 있습니다

일반적이지 않은 HID 장치에 액세스할 수 없다면 대체 보조 키보드 (예: Elgato Stream Deck, Jabra) 헤드셋, X키) 및 이국적인 게임패드 지원 등의 기능을 제공합니다. 데스크톱용 게임패드 게임패드 입력 (버튼, 조이스틱, 트리거) 및 출력에 HID를 사용하는 경우가 많습니다. (LED, 잡음) 게임패드 입력 및 출력이 제대로 작동하지 않음 웹 브라우저에는 특정 기기에 대한 맞춤 로직이 필요한 경우가 많습니다. 이는 지속 불가능하며 노인 및 흔하지 않은 기기입니다. 또한 브라우저가 동작의 쿼크에 의존하게 합니다. 확인할 수 있습니다.

용어

HID는 보고서와 보고서 설명자라는 두 가지 기본 개념으로 구성됩니다. 보고서는 기기와 소프트웨어 클라이언트 간에 교환되는 데이터입니다. 보고서 설명자는 기기에서 제공하는 데이터의 형식과 의미를 지원합니다

HID (휴먼 인터페이스 장치)는 인간에게 출력을 제공합니다 또한 HID 프로토콜을 의미하며 안전하게 통신하도록 설계된 장치 간의 양방향 통신을 설치 절차를 간소화할 수 있습니다. HID 프로토콜은 원래 USB 장치를 위한 것이지만, 그 이후로 다른 많은 프로토콜을 통해 구현되어 왔지만, 블루투스 등 다양한 기능이 있습니다.

애플리케이션과 HID 기기는 다음 세 가지 보고서 유형을 통해 바이너리 데이터를 교환합니다.

보고서 유형 설명
보고서 입력 기기에서 애플리케이션으로 전송되는 데이터 (예: 버튼 누르기)
출력 보고서 애플리케이션에서 기기로 전송되는 데이터 (예: 키보드 백라이트를 켜기 위한 요청)
기능 보고서 양방향으로 전송될 수 있는 데이터입니다. 형식은 기기에 따라 다릅니다.

보고서 설명자는 지원되는 보고서의 바이너리 형식을 설명합니다. 있습니다. 계층 구조이며 보고서를 서로 다른 그룹으로 묶을 수 있습니다. 최상위 컬렉션 내의 컬렉션입니다. 설명자의 형식은 다음과 같습니다. 사전 정의된 4개의 nginx 포드를 설정합니다

HID 사용은 표준화된 입력 또는 출력을 참조하는 숫자 값입니다. 용도 값을 통해 기기는 기기의 의도된 용도를 설명하고 볼 수 있습니다. 예를 들어 하나는 마우스 버튼을 클릭합니다. 또한 사용량은 사용량 페이지로 구성되어 있으며, 기기 또는 보고서의 상위 수준 카테고리 표시를 뜻합니다.

WebHID API 사용

특성 감지

WebHID API가 지원되는지 확인하려면 다음을 사용합니다.

if ("hid" in navigator) {
  // The WebHID API is supported.
}

HID 연결 열기

WebHID API는 웹사이트 UI가 차단될 수 있습니다. 이는 HID 데이터를 수신할 수 있으므로 중요합니다. 들을 방법이 필요하기 때문입니다.

HID 연결을 열려면 먼저 HIDDevice 객체에 액세스합니다. 이를 위해 다음과 같은 작업을 수행할 수 있습니다. 또는 navigator.hid.requestDevice() 또는 navigator.hid.getDevices()에서 선택하세요. 웹사이트에 액세스 권한이 부여된 기기 목록을 반환합니다. 확인할 수 있습니다

navigator.hid.requestDevice() 함수는 는 필터를 정의합니다. USB 공급업체와 연결된 모든 기기와 매칭하는 데 사용됩니다. 식별자 (vendorId), USB 제품 식별자 (productId), 사용 페이지 값 (usagePage)과 사용 값 (usage)이 있습니다. 이러한 정보는 USB ID 저장소HID 사용 표 문서를 참조하세요.

이 함수에서 반환하는 여러 HIDDevice 객체는 동일한 실제 기기의 HID 인터페이스

// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2006 // Joy-Con Left
  },
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2007 // Joy-Con Right
  }
];

// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
// Get all devices the user has previously granted the website access to.
const devices = await navigator.hid.getDevices();
드림 <ph type="x-smartling-placeholder">
</ph> 웹사이트에 표시된 HID 기기 메시지의 스크린샷
Nintendo Switch Joy-Con을 선택하는 사용자 프롬프트

다음과 같이 선택사항인 exclusionFilters 키를 사용할 수도 있습니다. 브라우저 선택 도구에서 일부 기기를 제외하는 navigator.hid.requestDevice() 예를 들어 고장난 것으로 알려진 것들이 있습니다.

// Request access to a device with vendor ID 0xABCD. The device must also have
// a collection with usage page Consumer (0x000C) and usage ID Consumer
// Control (0x0001). The device with product ID 0x1234 is malfunctioning.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 }],
  exclusionFilters: [{ vendorId: 0xabcd, productId: 0x1234 }],
});

HIDDevice 객체에는 기기의 USB 공급업체 및 제품 식별자가 포함됩니다. 있습니다. collections 속성은 계층 구조로 초기화됩니다. 기기의 보고서 형식에 대한 설명입니다.

for (let collection of device.collections) {
  // An HID collection includes usage, usage page, reports, and subcollections.
  console.log(`Usage: ${collection.usage}`);
  console.log(`Usage page: ${collection.usagePage}`);

  for (let inputReport of collection.inputReports) {
    console.log(`Input report: ${inputReport.reportId}`);
    // Loop through inputReport.items
  }

  for (let outputReport of collection.outputReports) {
    console.log(`Output report: ${outputReport.reportId}`);
    // Loop through outputReport.items
  }

  for (let featureReport of collection.featureReports) {
    console.log(`Feature report: ${featureReport.reportId}`);
    // Loop through featureReport.items
  }

  // Loop through subcollections with collection.children
}

HIDDevice 기기는 기본적으로 '닫힘' 상태로 반환됩니다. 이어야 하며 open()를 호출하여 열 수 있습니다.

// Wait for the HID connection to open before sending/receiving data.
await device.open();

입력 보고서 수신

HID 연결이 설정되면 사용자가 들어오는 입력을 처리할 수 있습니다. 기기에서 "inputreport" 이벤트를 수신 대기하여 보고합니다. 이러한 이벤트 HID 데이터를 DataView 객체(data)로 포함(HID 데이터가 속한 HID 기기) (device) 및 입력 보고서와 연결된 8비트 보고서 ID입니다. (reportId)

<ph type="x-smartling-placeholder">
</ph> 빨간색과 파란색 닌텐도 스위치 사진입니다.
Nintendo Switch Joy-Con 기기

계속해서 이전 예를 들자면, 아래 코드는 사용자가 Joy-Con Right 기기에서 어떤 버튼을 눌렀는지에 따라 집에서 시도해 보세요.

device.addEventListener("inputreport", event => {
  const { data, device, reportId } = event;

  // Handle only the Joy-Con Right device and a specific report ID.
  if (device.productId !== 0x2007 && reportId !== 0x3f) return;

  const value = data.getUint8(0);
  if (value === 0) return;

  const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
  console.log(`User pressed button ${someButtons[value]}.`);
});

출력 보고서 전송

HID 기기로 출력 보고서를 보내려면 출력 보고서 (reportId) 및 바이트를 BufferSource (data)으로 device.sendReport() 보고서가 완료되면 반환된 프로미스가 해결됩니다. 전송됩니다. HID 기기가 보고서 ID를 사용하지 않는 경우 reportId를 0으로 설정합니다.

아래 예는 Joy-Con 기기에 적용되며 이를 만드는 방법을 보여줍니다. 출력 보고서 등이 뒤섞여 있습니다.

// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));

// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));

기능 보고서 주고받기

기능 보고서는 두 범위 모두에서 이동할 수 있는 유일한 HID 데이터 보고서 유형입니다. 있습니다. HID 장치 및 애플리케이션이 표준화되지 않은 데이터 레이크와 HID 데이터. 입력 및 출력 보고서와 달리 특성 보고서는 수신되거나 정기적으로 전송합니다.

<ph type="x-smartling-placeholder">
</ph> 검은색과 은색 노트북 컴퓨터 사진입니다.
노트북 키보드

HID 기기로 기능 보고서를 전송하려면 연결된 8비트 보고서 ID를 특성 보고서 (reportId)와 바이트를 BufferSource (data)으로 사용하여 다음을 수행합니다. device.sendFeatureReport() 반환된 프로미스는 보고서가 전송됩니다. HID 기기가 보고서 ID를 사용하지 않는 경우 reportId를 0으로 설정합니다.

아래 예에서는 기능 보고서의 사용 방법을 보여줍니다. Apple 키보드 백라이트 기기를 요청한 후 열고 깜박이게 합니다.

const waitFor = duration => new Promise(r => setTimeout(r, duration));

// Prompt user to select an Apple Keyboard Backlight device.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});

// Wait for the HID connection to open.
await device.open();

// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
  // Turn off
  await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
  await waitFor(100);
  // Turn on
  await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
  await waitFor(100);
}

HID 기기에서 기능 보고서를 수신하려면 8비트 보고서 ID 기능 보고서 (reportId)와 관련된 항목: device.receiveFeatureReport() 반환된 프로미스는 기능 보고서의 콘텐츠가 포함된 DataView 객체입니다. HID 기기에서 보고서 ID를 사용하지 않으면 reportId를 0으로 설정합니다.

// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);

// Read feature report contents with dataView.getInt8(), getUint8(), etc...

연결 및 연결 해제 상태 듣기

HID 장치에 대한 액세스 권한을 부여받은 웹사이트는 "connect"를 수신 대기하여 연결 및 연결 해제 이벤트를 적극적으로 수신합니다. 및 "disconnect" 이벤트.

navigator.hid.addEventListener("connect", event => {
  // Automatically open event.device or warn user a device is available.
});

navigator.hid.addEventListener("disconnect", event => {
  // Remove |event.device| from the UI.
});

HID 기기에 대한 액세스 취소

웹사이트에서 더 이상 사용되지 않는 HID 기기에 액세스하기 위한 권한을 정리할 수 있음 HIDDevice 인스턴스에서 forget()를 호출하여 유지에 관심이 있는 경우 대상 많은 사람이 공유하는 컴퓨터에서 사용되는 교육용 웹 애플리케이션을 예로 들 수 있습니다. 누적된 사용자 생성 권한이 많아지면 있습니다.

단일 HIDDevice 인스턴스에서 forget()를 호출하면 모든 인스턴스에 대한 액세스 권한이 취소됩니다 물리적 장치에 있는 HID 인터페이스입니다.

// Voluntarily revoke access to this HID device.
await device.forget();

forget()는 Chrome 100 이상에서 사용할 수 있으므로 다음 기능이 사용 설정되어 있는지 확인하세요. 다음과 같이 지원됩니다.

if ("hid" in navigator && "forget" in HIDDevice.prototype) {
  // forget() is supported.
}

개발자 팁

내부 페이지(about://device-log)를 사용하면 Chrome에서 HID를 쉽게 디버깅할 수 있습니다. 한곳에서 모든 HID 및 USB 기기 관련 이벤트를 확인할 수 있습니다.

<ph type="x-smartling-placeholder">
</ph> HID를 디버그하는 내부 페이지의 스크린샷
HID를 디버그하는 Chrome 내부 페이지

HID 기기 덤프용 HID 탐색기 확인 정보를 사람이 읽을 수 있는 형식으로 변환합니다. 사용 값을 각 HID 사용.

대부분의 Linux 시스템에서 HID 기기는 기본값입니다. Chrome에서 HID 기기를 열 수 있도록 하려면 새 udev 규칙을 따릅니다. /etc/udev/rules.d/50-yourdevicename.rules에 다음 명령어로 파일을 만듭니다. 다음 콘텐츠:

KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

위 줄에서 기기가 Nintendo Switch인 경우 [yourdevicevendor]057e입니다. 예를 들어 Joy-Con이요. 더 구체적인 경우 ATTRS{idProduct}를 추가할 수도 있습니다. 있습니다. user님이 plugdev 그룹의 구성원인지 확인하세요. 그런 다음 기기를 다시 연결합니다.

브라우저 지원

WebHID API는 모든 데스크톱 플랫폼 (ChromeOS, Linux, macOS, 및 Windows)에서 지원됩니다.

데모

일부 WebHID 데모는 web.dev/hid-examples에 있습니다. 한번 가보세요!

보안 및 개인 정보 보호

사양 작성자는 인코더-디코더 API를 사용하여 WebHID API를 강력한 웹 플랫폼 기능에 대한 액세스 제어에 정의된 원칙 사용자 제어, 투명성, 인체공학을 포함합니다. 이 기능을 사용해 API는 기본적으로 단일 항목에만 액세스 권한을 부여하는 권한 모델로 관리됩니다. 최대 24개의 HID 기기를 실행할 수 있습니다 사용자 프롬프트에 응답하여 사용자는 활성 특정 HID 기기를 선택하는 단계를 수행합니다.

보안의 장단점을 알아보려면 보안 및 개인 정보 보호 고려사항 섹션을 참조하세요.

또한 Chrome은 각 최상위 컬렉션의 사용을 검사하고 보호된 사용 (예: 일반 키보드, 마우스)이 있는 최상위 컬렉션 웹사이트에서 정의된 보고서를 전송하거나 수신할 수 없습니다 컬렉션입니다. 보호되는 사용의 전체 목록은 공개적으로 사용할 수 있습니다.

보안에 민감한 HID 기기 (예: 더 강력한 인증)을 차단하는 것은 Chrome에서 차단됩니다. USB 차단 목록HID 차단 목록 파일.

의견

Chrome팀은 Chrome OS에 대한 여러분의 의견과 경험을 WebHID API를 통해 구현됩니다.

API 설계에 대해 알려주세요.

API에서 예상대로 작동하지 않는 부분이 있나요? 아니면 Google에서 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되었나요?

WebHID API GitHub 저장소에서 사양 문제를 신고하거나 의견을 추가하세요. 추가할 수 있습니다

구현 문제 신고

Chrome 구현에서 버그를 발견하셨나요? 아니면 구현이 어떻게 해야 할까요?

WebHID 버그 신고 방법을 참고하세요. 최대한 많은 버그 재현을 위한 간단한 안내를 제공하고, 구성요소Blink>HID로 설정됨 Glitch는 쉽고 빠르게 재현할 수 있습니다.

지지 표시

WebHID API를 사용할 계획이신가요? 여러분의 공개적 후원은 Chrome 팀은 기능의 우선순위를 정하고 다른 브라우저 공급업체에 도움이 될 수 있습니다

해시태그를 사용하여 @ChromiumDev에 트윗을 보냅니다. #WebHID을(를) 방문하여 알려주세요. 사용자가 어디에서 어떻게 사용하는지 파악할 수 있습니다

유용한 링크

감사의 말씀

이 기사를 검토해 주신 맷 레이놀즈조 메들리님께 감사드립니다. 사라 쿠르페스의 Nintendo Switch 사진: 빨간색과 파란색, 검은색과 은색 노트북 컴퓨터 사진: Athul Cyriac Ajay, Unsplash