Files
2nd/10_Wiki/Topics/Coding/Web_WebTransport_HID_USB.md
T
2026-05-10 22:08:15 +09:00

8.0 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
web-webtransport-hid-usb WebTransport / WebHID / WebUSB / WebSerial Coding draft B conceptual 2026-05-09 2026-05-09
web
transport
hardware
vibe-coding
language applicable_to
TS
Frontend
WebTransport
WebHID
WebUSB
WebSerial
Web Bluetooth
Web NFC
hardware API

WebTransport / WebHID / WebUSB

Browser 가 native-like 영역. WebTransport (HTTP/3 stream), WebHID (game controller, MIDI), WebUSB (firmware flash), WebSerial (Arduino).

📖 핵심 개념

  • WebTransport: WebSocket 보다 빠름 (HTTP/3, UDP).
  • WebHID: human interface device.
  • WebUSB: 임의 USB.
  • WebSerial: serial port.

💻 코드 패턴

WebTransport

const transport = new WebTransport('https://server.example.com/wt');
await transport.ready;

// Bidirectional stream
const stream = await transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode('hello'));
await writer.close();

const reader = stream.readable.getReader();
const { value } = await reader.read();
console.log(new TextDecoder().decode(value));

→ HTTP/3 + QUIC. Multiple stream 가 1 connection.

Datagram (unreliable, fast)

const writer = transport.datagrams.writable.getWriter();
await writer.write(new Uint8Array([1, 2, 3]));

const reader = transport.datagrams.readable.getReader();
const { value } = await reader.read();

→ UDP-like. Game / WebRTC alternative.

WebTransport server (Node)

// 일부 server library 만 지원
import { Http3Server } from '@fails-components/webtransport';

const server = new Http3Server({ port: 4433, host: '0.0.0.0' });
server.startServer();

const sessions = await server.sessionStream('/wt');
for await (const session of sessions) {
  // ... handle
}

→ HTTP/3 stack 필요. Bun / Node 가 부분 지원.

WebHID (game controller)

const devices = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0x054c }],  // Sony
});

const device = devices[0];
await device.open();

device.addEventListener('inputreport', (e) => {
  const { data, reportId } = e;
  // Parse report (game controller state)
});

MIDI controller

const access = await navigator.requestMIDIAccess();

for (const input of access.inputs.values()) {
  input.onmidimessage = (e) => {
    const [status, note, velocity] = e.data;
    // Note on, note off, ...
  };
}

WebUSB (firmware update)

const device = await navigator.usb.requestDevice({
  filters: [{ vendorId: 0x2341 }],  // Arduino
});

await device.open();
await device.selectConfiguration(1);
await device.claimInterface(0);

// Send
await device.transferOut(1, new TextEncoder().encode('hello'));

// Receive
const r = await device.transferIn(2, 64);
console.log(new Uint8Array(r.data!.buffer));

→ Sketch upload, firmware flash.

WebSerial (Arduino, ESP32)

const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });

const writer = port.writable!.getWriter();
await writer.write(new TextEncoder().encode('led on\n'));

const reader = port.readable!.getReader();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  console.log(new TextDecoder().decode(value));
}

Web Bluetooth

const device = await navigator.bluetooth.requestDevice({
  filters: [{ services: ['heart_rate'] }],
});

const server = await device.gatt!.connect();
const service = await server.getPrimaryService('heart_rate');
const char = await service.getCharacteristic('heart_rate_measurement');

await char.startNotifications();
char.addEventListener('characteristicvaluechanged', (e) => {
  const value = (e.target as any).value;
  console.log('heart rate:', value.getUint8(1));
});

Web NFC (Android)

if ('NDEFReader' in window) {
  const ndef = new NDEFReader();
  await ndef.scan();
  
  ndef.onreading = ({ message }) => {
    for (const r of message.records) {
      console.log(r.recordType, r.data);
    }
  };
}

→ Android Chrome 만.

Permission

모든 = user gesture (click) 필수.
사용자 가 device picker 에서 grant.
HTTPS 만.

Use case

WebTransport: WebSocket 의 modern, low-latency game / streaming.
WebHID: Game controller, MIDI, custom HID.
WebUSB: Hardware programmer, firmware tool.
WebSerial: Arduino IDE in browser, debugging.
Web Bluetooth: IoT, fitness tracker.
Web NFC: Tag reader, payment (Android).

Browser support

WebTransport: Chrome 97+, FF / Safari 가 부분.
WebHID: Chrome 89+, Edge.
WebUSB: Chrome 61+. FF / Safari 가 안 (security 우려).
WebSerial: Chrome 89+.
Web Bluetooth: Chrome 56+.
Web NFC: Chrome Android 81+.

→ 대부분 Chrome / Edge / Opera 만.

Permission Policy

<!-- iframe 가 사용 -->
<iframe allow="hid; usb; serial; bluetooth"></iframe>

Reconnect

// USB
navigator.usb.addEventListener('connect', (e) => {
  // device 가 다시 connected
});
navigator.usb.addEventListener('disconnect', (e) => {});

// 같은 device 가 자동 reconnect 안 됨 — 사용자 picker 다시.

Persistent permission

// 이전 grant 된 device list
const devices = await navigator.hid.getDevices();
for (const d of devices) {
  if (!d.opened) await d.open();
}

→ User 가 picker 안 다시 — handle 가 영구.

함정

- Chrome 만 = userbase 한계.
- HID parsing 어려움 (binary).
- Connection drop 자주.
- Sandbox 안에서만 (system file system 안 됨).
- HTTPS only.

Native vs Web

Web:
- Distribution easy
- 자동 update
- 작은 surface (특정 device 만)

Native:
- 큰 권한
- Performance
- 모든 device

→ 작은 use case = Web. 큰 = Native.

WebGPU (powerful)

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter!.requestDevice();
// ... shader, pipeline, render

→ GPU 사용. ML / 3D.

Frontend_WebGPU_Patterns.

File over USB (e.g. ADB)

// Chrome OS 의 Android device debug
const device = await navigator.usb.requestDevice({
  filters: [{ classCode: 0xff, subclassCode: 0x42 }],  // ADB
});

→ Chrome OS 의 Android Studio web 같은 것.

Audio / video device

// MediaDevices API (다름)
const stream = await navigator.mediaDevices.getUserMedia({
  audio: { deviceId: '...' },
  video: { deviceId: '...' },
});

→ Camera, microphone, screen share.

WebRTC vs WebTransport

WebRTC:
- Peer-to-peer
- DTLS + SRTP
- 복잡 setup (signaling, ICE)

WebTransport:
- Client-server
- HTTP/3 + QUIC
- Simple

→ Game / streaming = WebTransport. Conferencing = WebRTC.

Browser WASM 가 native-like

+ 위 device API
+ WebGPU (GPU)
+ WASM (CPU)
+ File System Access (file)
+ Service Worker (background)
+ Push API (notification)
+ Periodic Sync

→ "Web 가 Win32 / macOS API 와 비슷" 가 modern.

Production 사용

  • StackBlitz / WebContainer — Node in browser
  • Figma — file, hardware (palette device)
  • Photopea — Photoshop in browser
  • VS Code Web — File system + ext
  • Adafruit — Arduino in browser (WebSerial + WebUSB)

🤔 의사결정 기준

작업 추천
Low-latency game/stream WebTransport
Game controller / MIDI WebHID
Firmware flash WebUSB
Arduino REPL WebSerial
IoT 통신 Web Bluetooth
NFC tag Web NFC (Android)
Cross-browser 필요 WebSocket / Bluetooth fallback X
GPU compute WebGPU

안티패턴

  • 모든 browser 가정: Chrome 만 흔함.
  • User gesture 없이: error.
  • HTTPS 안: blocked.
  • HID report parse 무기준: binary 잘못.
  • Disconnect handling 없음: hang.
  • Persistent permission 무시: 매번 picker.
  • WebTransport server 없이: fail.

🤖 LLM 활용 힌트

  • WebTransport = HTTP/3 stream + datagram (WebSocket 의 모던).
  • WebHID / WebUSB / WebSerial = Chrome 만.
  • User gesture + HTTPS 의무.
  • Native vs Web — 작은 use case.

🔗 관련 문서