Architecture¶
Components¶
| Package | Responsibility |
|---|---|
cmd/rdpserver |
Process bootstrap, shutdown, and Windows service mode selection |
internal/web |
HTTP server, index handler, WebSocket upgrade, and session spawn |
internal/session |
Session admission manager and per-session proxy workers |
internal/broker |
Temporary Windows account lifecycle and credential broker loop |
internal/display |
Pure-Go RDP client interface and grdp-backed implementation |
ui |
Embedded static HTML/JS canvas client |
Component diagram¶
flowchart TD
Browser["Browser (WebSocket)"] -->|"/ws/rdp"| Web["internal/web\nHTTP + WebSocket"]
Web -->|CredRequest chan| Broker["internal/broker\nCredential broker"]
Broker -->|Win32 NetUserAdd| WinAccounts["Windows local accounts"]
Web -->|SessionEvent chan| Manager["internal/session\nSession manager"]
Manager -->|display.Connect| Display["internal/display\ngrdp RDP client"]
Display -->|RDP| WinRDP["Windows RDP Server"]
Runtime flow¶
- Client connects to
/ws/rdp. - Session manager enforces
MAX_SESSIONS. - Broker provisions a temporary local user and returns credentials.
- Session worker opens an RDP connection via the pure-Go
grdpclient. - Bitmap tile updates are JPEG-encoded and forwarded to the browser as JSON WebSocket messages.
- Keyboard and mouse input arrives as JSON messages and is forwarded to the RDP session.
- On close, error, or shutdown the temporary account is deleted and capacity is released.
sequenceDiagram
participant Browser
participant Web
participant Manager
participant Broker
participant Display
Browser->>Web: WebSocket connect /ws/rdp
Web->>Manager: Admit(sessionID)
Web->>Broker: CredRequest
Broker-->>Web: CredResponse (username, password)
Web->>Display: display.Connect (grdp)
loop Proxy
Display-->>Web: Tile (JPEG bitmap)
Web-->>Browser: JSON tile message
Browser->>Web: JSON input message
Web->>Display: KeyDown/MouseMove/…
end
Browser->>Web: close
Web->>Manager: SessionClosed event
Web->>Broker: SessionClosed event → delete temp user
Wire protocol¶
Messages between browser and server are JSON objects sent over WebSocket.
Server → Browser (tile update)
{ "type": "tile", "x": 0, "y": 0, "w": 200, "h": 100, "data": "<base64 JPEG>" }
Browser → Server (input events)
{ "type": "keydown", "scancode": 28 }
{ "type": "keyup", "scancode": 28 }
{ "type": "mousemove", "x": 320, "y": 240 }
{ "type": "mousedown", "button": 0, "x": 320, "y": 240 }
{ "type": "mouseup", "button": 0, "x": 320, "y": 240 }
{ "type": "mousewheel", "delta": 3 }
Shutdown behaviour¶
| Mode | Signal source |
|---|---|
| Console | OS signals (SIGINT, SIGTERM) cancel context |
| Windows Service | SCM stop/shutdown events cancel context |
A shared shutdown channel closes all worker loops and triggers temporary account cleanup before the process exits.