--- 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 ``` ### 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]]