[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
@@ -0,0 +1,347 @@
---
id: web-webtransport-hid-usb
title: WebTransport / WebHID / WebUSB / WebSerial
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [web, transport, hardware, vibe-coding]
tech_stack: { language: "TS", applicable_to: ["Frontend"] }
applied_in: []
aliases: [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
```ts
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)
```ts
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)
```ts
// 일부 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)
```ts
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
```ts
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)
```ts
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)
```ts
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
```ts
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)
```ts
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
```html
<!-- iframe 가 사용 -->
<iframe allow="hid; usb; serial; bluetooth"></iframe>
```
### Reconnect
```ts
// USB
navigator.usb.addEventListener('connect', (e) => {
// device 가 다시 connected
});
navigator.usb.addEventListener('disconnect', (e) => {});
// 같은 device 가 자동 reconnect 안 됨 — 사용자 picker 다시.
```
### Persistent permission
```ts
// 이전 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)
```ts
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)
```ts
// 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
```ts
// 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.
## 🔗 관련 문서
- [[Web_WebRTC_Realtime]]
- [[Web_WebSocket_Reconnect]]
- [[Frontend_WebGPU_Patterns]]