RustDesk web client
Browser-based RustDesk client embedded in rustdesk-server. Surfaced from the
admin dashboard as a "Connect" button on the Devices page.
Architecture (one-liner)
Plain TypeScript SPA → talks WebSocket directly to hbbs:21118 (rendezvous)
and hbbr:21119 (relay) → protobufjs for wire format → libsodium-wrappers
for crypto → WebCodecs for video/audio decode → <canvas> for display.
No frameworks. ~1 MB minified.
Building
./build.sh # bundles to dist/bundle.{js,css}
git add dist/
dist/ is committed so cargo build -p hbbs doesn't need Node. Anyone
touching code under src/ should re-run ./build.sh and commit the new
dist/ files in the same commit.
Regenerating proto bindings
Rare — only when libs/hbb_common bumps and proto fields change:
npm run protogen
./build.sh
git add src/proto/generated.* dist/
Layout
src/
main.ts boot: read #custom-config, init transport
crypto.ts libsodium wrapper
proto/ generated protobufjs static modules (committed)
transport/ rendezvous WS, relay WS, secure handshake state machine
decode/ video (WebCodecs VideoDecoder), audio (AudioDecoder)
input/ mouse/keyboard capture → protobuf MouseEvent/KeyEvent
ui/ canvas + toolbar + style.css
audit.ts POST /api/audit/conn with admin cookie
dist/
bundle.js + .css committed esbuild output
Wire-protocol references
/Users/sn0/Desktop/rustdesk-server/libs/hbb_common/protos/{rendezvous,message}.proto/Users/sn0/Desktop/rustdesk/src/client.rs— desktop-client connect/secure/login state machine/Users/sn0/Desktop/rustdesk-server/libs/hbb_common/src/tcp.rs:296-344— secretbox nonce derivation (8-byte LE counter, separate per direction)