### Example: Simple VNC Server with Custom Framebuffer Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md This Rust example creates a VNC server with a custom resolution and populates its framebuffer with a color gradient. It then updates the display and starts the server, showing how to manually manage the pixel data. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { let server = VncServer::new(800, 600); server.set_password(Some("test".to_string())); // Create test pattern let mut pixels = vec![0u8; 800 * 600 * 4]; // RGBA32 for y in 0..600 { for x in 0..800 { let offset = (y * 800 + x) * 4; pixels[offset] = (x * 255 / 800) as u8; // R pixels[offset + 1] = (y * 255 / 600) as u8; // G pixels[offset + 2] = 128; // B pixels[offset + 3] = 255; // A } } server.update_framebuffer(&pixels, 0, 0, 800, 600); server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Run rustvncserver Examples Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Instructions to run example VNC servers provided by the rustvncserver project. ```bash cargo run --example simple_server cargo run --example headless_server ``` -------------------------------- ### Quick Start: Basic VNC Server in Rust Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md A minimal Rust program demonstrating how to create and start a VNC server with default settings. It initializes the VncServer, optionally sets a password, and begins listening on a specified port. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { // Create VNC server let server = VncServer::new(1920, 1080); // Optional: Set password server.set_password(Some("secret".to_string())); // Start listening server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Install libjpeg-turbo Development Files (Ubuntu/Debian) Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Installs the development files for libjpeg-turbo on Ubuntu or Debian-based systems, a prerequisite for enabling the TurboJPEG feature in rustvncserver. ```bash sudo apt-get install libturbojpeg0-dev ``` -------------------------------- ### Rust Toolchain Installation Command Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This command downloads and executes the Rustup script to install or update the Rust toolchain. It ensures the latest stable version of Rust is available, which is a prerequisite for building the RustVNC server. ```bash curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -------------------------------- ### Install libjpeg-turbo (macOS) Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Installs libjpeg-turbo on macOS using Homebrew, which is required for the TurboJPEG feature of rustvncserver. ```bash brew install jpeg-turbo ``` -------------------------------- ### Example: Handling VNC Client Events Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Demonstrates how to set up a VNC server and concurrently handle client events such as connections, disconnections, pointer movements, and key presses. It uses a Tokio spawned task to asynchronously process events from the server. ```rust use rustvncserver::{VncServer, ServerEvent}; #[tokio::main] async fn main() -> Result<(), Box> { let server = VncServer::new(1920, 1080); // Get event receiver let mut events = server.events(); // Handle events in background tokio::spawn(async move { while let Ok(event) = events.recv().await { match event { ServerEvent::ClientConnected { id, address } => { println!("Client {} connected from {}", id, address); } ServerEvent::PointerEvent { x, y, button_mask, .. } => { println!("Pointer: ({}, {}) buttons={}", x, y, button_mask); } ServerEvent::KeyEvent { key, pressed, .. } => { println!("Key: {} {}", key, if pressed { "pressed" } else { "released" }); } _ => {} } } }); server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Basic VNC Server Setup in Rust Source: https://context7.com/rustvnc/rustvncserver/llms.txt Demonstrates how to initialize and run a VNC server using the rustvncserver library. It includes setting up environment-based logging, creating a VNC server instance with specified dimensions and a password, and listening on a specific port. The 'debug-logging' feature provides detailed connection and protocol information. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { // Initialize logger (debug-logging feature must be enabled) env_logger::Builder::from_env( env_logger::Env::default().default_filter_or("debug") ).init(); let (server, _events) = VncServer::new( 800, 600, "Debug Server".to_string(), Some("test".to_string()), ); // With debug-logging enabled, you'll see: // - Client IP addresses and connection details // - Protocol handshake messages // - Encoding selection and statistics // - Compression ratios and performance metrics // - Framebuffer update information server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Create and Listen for VNC Server Connections (Rust) Source: https://context7.com/rustvnc/rustvncserver/llms.txt Demonstrates how to create a VNC server instance with specific dimensions, a desktop name, and optional password authentication. It also shows how to handle client connection and disconnection events asynchronously and start listening for incoming connections on a specified port. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { // Create server with 1920x1080 resolution let (server, mut events) = VncServer::new( 1920, 1080, "My Desktop".to_string(), Some("secret".to_string()), // Optional password ); // Handle server events in background task tokio::spawn(async move { while let Some(event) = events.recv().await { match event { rustvncserver::ServerEvent::ClientConnected { id, address } => { println!("Client {} connected from {}", id, address); } rustvncserver::ServerEvent::ClientDisconnected { id } => { println!("Client {} disconnected", id); } _ => {} } } }); // Start listening on port 5900 (blocks until server stops) server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Connect to VNC Viewer in Listening Mode (Rust) Source: https://context7.com/rustvnc/rustvncserver/llms.txt Establishes a reverse connection to a VNC viewer that is listening for incoming connections. The VNC viewer must be started with the '-listen' option. This is useful for connecting through firewalls or when the server cannot directly reach the viewer. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { let (server, _events) = VncServer::new( 1024, 768, "Reverse Connection".to_string(), None, ); // Create initial framebuffer content let pixels = vec![100u8; 1024 * 768 * 4]; // Gray screen server .framebuffer() .update_cropped(&pixels, 0, 0, 1024, 768) .await?; // Connect to a viewer listening on port 5500 // Viewer must be started with: vncviewer -listen 5500 server.connect_reverse("192.168.1.100", 5500).await?; println!("Connected to viewer at 192.168.1.100:5500"); // Keep server running tokio::signal::ctrl_c().await?; Ok(()) } ``` -------------------------------- ### Dynamically Resize Framebuffer (Rust) Source: https://context7.com/rustvnc/rustvncserver/llms.txt Demonstrates how to dynamically resize the VNC framebuffer and update connected clients. The server starts with initial dimensions, then resizes and updates the content. This is useful for adapting to different display resolutions. ```rust use rustvncserver::VncServer; use tokio::time::{sleep, Duration}; #[tokio::main] async fn main() -> Result<(), Box> { let (server, _events) = VncServer::new( 800, 600, "Resizable Desktop".to_string(), None, ); let framebuffer = server.framebuffer().clone(); tokio::spawn(async move { if let Err(e) = server.listen(5900).await { eprintln!("Server error: {}", e); } }); sleep(Duration::from_secs(5)).await; // Resize to 1024x768 println!("Resizing framebuffer to 1024x768"); framebuffer.resize(1024, 768).await; // Create new content for resized framebuffer let pixels = vec![255u8; 1024 * 768 * 4]; // White screen framebuffer .update_cropped(&pixels, 0, 0, 1024, 768) .await?; tokio::signal::ctrl_c().await?; Ok(()) } ``` -------------------------------- ### Secure Deployment: VNC over SSH Tunnel Example Source: https://github.com/rustvnc/rustvncserver/blob/main/SECURITY.md This example demonstrates how to establish a secure VNC connection by tunneling the VNC port over SSH. This encrypts the VNC traffic, protecting it from eavesdropping and man-in-the-middle attacks. It assumes the VNC server is running on the remote machine and accessible via localhost:5900 from the client's perspective after the tunnel is established. ```bash ssh -L 5900:localhost:5900 user@vnc-server # Then connect to localhost:5900 from your VNC client ``` -------------------------------- ### Update Framebuffer with Pixel Data (Rust) Source: https://context7.com/rustvnc/rustvncserver/llms.txt Illustrates how to update the VNC server's framebuffer with new pixel data. This example shows how to create a gradient pattern and update the entire framebuffer, as well as how to update a specific rectangular region of the framebuffer with new data. ```rust use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { let (server, _events) = VncServer::new( 800, 600, "Test Pattern".to_string(), None, // No password ); // Create gradient test pattern (RGBA32 format) let mut pixels = vec![0u8; 800 * 600 * 4]; for y in 0..600 { for x in 0..800 { let offset = (y * 800 + x) * 4; pixels[offset] = (x * 255 / 800) as u8; // R: horizontal gradient pixels[offset + 1] = (y * 255 / 600) as u8; // G: vertical gradient pixels[offset + 2] = 128; // B: constant blue pixels[offset + 3] = 255; // A: opaque } } // Update entire framebuffer server .framebuffer() .update_cropped(&pixels, 0, 0, 800, 600) .await?; // Update partial region (top-left 100x100) let small_region = vec![255u8; 100 * 100 * 4]; // White square server .framebuffer() .update_cropped(&small_region, 0, 0, 100, 100) .await?; server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Utilize TurboJPEG Hardware Acceleration - Rust Source: https://context7.com/rustvnc/rustvncserver/llms.txt Demonstrates the use of hardware-accelerated JPEG compression via the TurboJPEG feature for Tight encoding. This feature provides significant speed improvements by leveraging SIMD instructions. The code assumes libjpeg-turbo is installed and the 'turbojpeg' feature is enabled in Cargo.toml. ```rust // Install libjpeg-turbo first: // Ubuntu/Debian: apt-get install libturbojpeg0-dev // macOS: brew install jpeg-turbo // Windows: download from libjpeg-turbo.org use rustvncserver::VncServer; #[tokio::main] async fn main() -> Result<(), Box> { let (server, _events) = VncServer::new( 1920, 1080, "High Performance Server".to_string(), None, ); // TurboJPEG provides hardware-accelerated JPEG compression // - 2-6x faster than software JPEG // - Uses SIMD instructions (NEON on ARM, SSE2 on x86) // - Automatic when feature enabled // - Used for Tight encoding JPEG mode (quality 1-9) let photographic_content = vec![128u8; 1920 * 1080 * 4]; server .framebuffer() .update_cropped(&photographic_content, 0, 0, 1920, 1080) .await?; // Clients requesting Tight encoding with quality 1-9 // will automatically use TurboJPEG for JPEG compression server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### VncServer API: Initialization and Control Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Provides methods for creating, configuring, and controlling a VNC server instance. Includes functions for setting dimensions, starting/stopping the server, managing connections (reverse, repeater), updating the framebuffer, and handling specific VNC operations. ```rust impl VncServer { /// Create new server with given dimensions pub fn new(width: u16, height: u16) -> Self; /// Start listening on TCP port pub async fn listen(&self, port: u16) -> Result<()>; /// Connect to listening viewer (reverse connection) pub async fn connect_reverse(&self, host: &str, port: u16) -> Result<()>; /// Connect to repeater pub async fn connect_repeater(&self, host: &str, port: u16, id: &str) -> Result<()>; /// Update framebuffer region pub fn update_framebuffer(&self, data: &[u8], x: u16, y: u16, width: u16, height: u16); /// Resize framebuffer pub fn resize_framebuffer(&self, width: u16, height: u16); /// Schedule CopyRect operation pub fn schedule_copy_rect(&self, x: u16, y: u16, width: u16, height: u16, dx: i16, dy: i16); /// Execute scheduled CopyRect operations pub fn do_copy_rect(&self); /// Send clipboard text to all clients pub fn send_clipboard(&self, text: &str); /// Set authentication password pub fn set_password(&self, password: Option); /// Get event receiver pub fn events(&self) -> mpsc::Receiver; /// Stop server pub fn stop(&self); } ``` -------------------------------- ### Conventional Commits Format Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Examples of commit messages following the Conventional Commits specification, including types like 'feat', 'fix', 'docs', and scopes. ```bash type(scope): subject body (optional) footer (optional) feat(encoding): add support for ZSTD compression fix(auth): handle empty password correctly docs(readme): update installation instructions ``` -------------------------------- ### Build and Test rustvncserver Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Commands for cloning the repository, building the project, and running tests. Includes options for building with all features. ```bash # Clone your fork git clone https://github.com/YOUR_USERNAME/rustvncserver.git cd rustvncserver # Build cargo build # Run tests cargo test # Build with all features cargo build --all-features ``` -------------------------------- ### RustVNC Server Build and Test Commands Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md These commands are used to build the RustVNC server project in release mode for optimization, run all defined tests to ensure functionality, and generate and open the project's documentation. ```bash # Build library cargo build --release # Run tests cargo test # Build documentation cargo doc --open ``` -------------------------------- ### Generate and Open API Documentation Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Command to generate Rust documentation for the project and open it in a web browser. Supports building with all features. ```bash cargo doc --open --all-features ``` -------------------------------- ### VncServer Methods Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Documentation for the VncServer struct methods, including server creation, listening, event handling, and framebuffer updates. ```APIDOC ## VncServer Methods ### `new(width: u16, height: u16)` * **Description**: Create a new VNC server instance with the specified screen dimensions. * **Parameters**: * `width` (u16) - The width of the virtual screen. * `height` (u16) - The height of the virtual screen. * **Returns**: A new `VncServer` instance. ### `listen(&self, port: u16)` * **Description**: Start the VNC server and begin listening for incoming client connections on the specified TCP port. * **Parameters**: * `port` (u16) - The TCP port to listen on. * **Returns**: A `Result` indicating success or an error if the server fails to start. ### `connect_reverse(&self, host: &str, port: u16)` * **Description**: Establish a reverse connection to a listening VNC viewer. * **Parameters**: * `host` (&str) - The hostname or IP address of the VNC viewer. * `port` (u16) - The port the VNC viewer is listening on. * **Returns**: A `Result` indicating success or an error. ### `connect_repeater(&self, host: &str, port: u16, id: &str)` * **Description**: Connect to a VNC repeater. * **Parameters**: * `host` (&str) - The hostname or IP address of the VNC repeater. * `port` (u16) - The port the VNC repeater is listening on. * `id` (&str) - The identifier for this server connection. * **Returns**: A `Result` indicating success or an error. ### `update_framebuffer(&self, data: &[u8], x: u16, y: u16, width: u16, height: u16)` * **Description**: Update a specific region of the VNC server's framebuffer with new pixel data. * **Parameters**: * `data` (&[u8]) - A slice containing the raw pixel data (e.g., RGBA32). * `x` (u16) - The x-coordinate of the top-left corner of the region to update. * `y` (u16) - The y-coordinate of the top-left corner of the region to update. * `width` (u16) - The width of the region to update. * `height` (u16) - The height of the region to update. ### `resize_framebuffer(&self, width: u16, height: u16)` * **Description**: Resize the virtual framebuffer of the VNC server. * **Parameters**: * `width` (u16) - The new width of the framebuffer. * `height` (u16) - The new height of the framebuffer. ### `schedule_copy_rect(&self, x: u16, y: u16, width: u16, height: u16, dx: i16, dy: i16)` * **Description**: Schedule a CopyRect operation to efficiently copy screen regions. This is useful for scrolling or window dragging. * **Parameters**: * `x` (u16) - The x-coordinate of the source region. * `y` (u16) - The y-coordinate of the source region. * `width` (u16) - The width of the source region. * `height` (u16) - The height of the source region. * `dx` (i16) - The horizontal distance to copy the region to. * `dy` (i16) - The vertical distance to copy the region to. ### `do_copy_rect(&self)` * **Description**: Execute all scheduled CopyRect operations. ### `send_clipboard(&self, text: &str)` * **Description**: Send clipboard text content to all connected VNC clients. * **Parameters**: * `text` (&str) - The clipboard text to send. ### `set_password(&self, password: Option)` * **Description**: Set an optional password for VNC client authentication. * **Parameters**: * `password` (Option) - The password string, or `None` to disable password authentication. ### `events(&self)` * **Description**: Get a receiver for `ServerEvent`s. This allows the application to listen for and react to various VNC events like client connections, disconnections, pointer movements, and key presses. * **Returns**: An `mpsc::Receiver`. ### `stop(&self)` * **Description**: Stop the VNC server. ``` -------------------------------- ### Create Git Tag for Release Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Commands for creating and pushing a git tag to mark a new release version. ```bash git tag -a v1.x.x -m "Release v1.x.x" git push origin v1.x.x ``` -------------------------------- ### CPU vs Bandwidth Encoding Trade-off Visualization - RustVNC Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This visualization illustrates the trade-off between CPU usage and compression levels for various encoding methods in RustVNC. It shows a spectrum from Raw (low CPU, low compression) to ZYWRLE (high CPU, high compression), with Tight encoding recommended for a balance. ```text Low CPU High CPU Low Compression High Compression ↓ ↓ Raw → Hextile → Zlib → ZlibHex → ZRLE → Tight → ZYWRLE ``` -------------------------------- ### RustVNC Server: Encoding Priority Order Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This snippet illustrates the server's selection algorithm for VNC encodings when a client supports multiple options. It prioritizes encodings based on RFC 6143 best practices, aiming for optimal compression and performance. ```text 1. CopyRect (1) ← Handled separately, highest priority for region movement 2. Tight (7) ← Best compression with intelligent mode selection 3. TightPng (-260) ← PNG-only compression for browser-based clients 4. ZRLE (16) ← Good for text/UI with palette compression 5. ZYWRLE (17) ← Wavelet for low-bandwidth 6. ZlibHex (8) ← Zlib-compressed Hextile 7. Zlib (6) ← Fast general-purpose compression 8. Hextile (5) ← Tile-based encoding 9. Raw (0) ← Uncompressed fallback ``` -------------------------------- ### Run rustvncserver Tests Source: https://github.com/rustvnc/rustvncserver/blob/main/CONTRIBUTING.md Commands for running tests in the rustvncserver project, including options for capturing output and running specific tests. ```bash # Run all tests cargo test # Run tests with output cargo test -- --nocapture # Run specific test cargo test test_name # Run with all features cargo test --all-features ``` -------------------------------- ### Integration of Pixel Translation with Raw Encoding in Rust Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md Demonstrates how pixel translation is integrated into an encoding path, specifically for the Raw encoding. It checks if the client format is compatible with RGBA32 for a potential optimization (stripping alpha). Otherwise, it falls back to the full `translate_pixels` function. This highlights the principle that translation precedes encoding. ```rust // Example: Raw encoding let translated = if client_pixel_format.is_compatible_with_rgba32() { // Fast path: just strip alpha channel strip_alpha_channel(&pixel_data) } else { // Full translation translate::translate_pixels(&pixel_data, &server_format, &client_pixel_format) }; ``` -------------------------------- ### RustVNC: Process Client Input Events Source: https://context7.com/rustvnc/rustvncserver/llms.txt This snippet demonstrates how to receive and process various input events from connected VNC clients, including pointer movements, keyboard presses, and clipboard content. It utilizes Rust's async capabilities with `tokio` and the `rustvncserver` library. Dependencies include `rustvncserver` and `tokio`. ```rust use rustvncserver::{VncServer, ServerEvent}; #[tokio::main] async fn main() -> Result<(), Box> { let (server, mut events) = VncServer::new( 1280, 720, "Interactive Desktop".to_string(), Some("password".to_string()), ); // Handle all client events tokio::spawn(async move { while let Some(event) = events.recv().await { match event { ServerEvent::PointerEvent { client_id, x, y, button_mask } => { println!("Client {}: Pointer at ({}, {})", client_id, x, y); if button_mask & 0x01 != 0 { println!(" Left button pressed"); } if button_mask & 0x02 != 0 { println!(" Middle button pressed"); } if button_mask & 0x04 != 0 { println!(" Right button pressed"); } } ServerEvent::KeyEvent { client_id, key, pressed } => { let state = if pressed { "pressed" } else { "released" }; println!("Client {}: Key 0x{:X} {}", client_id, key, state); // Common keysyms (X11 standard) match key { 0xFF0D => println!(" -> Enter key"), 0xFF1B => println!(" -> Escape key"), 0x0061..=0x007A => println!(" -> Letter '{}'", (key as u8) as char), _ => {} // Ignore other keys } } ServerEvent::ClipboardReceived { client_id, text } => { println!("Client {}: Clipboard: {}", client_id, text); } ServerEvent::ClientConnected { id, address } => { println!("New client {} from {}", id, address); } ServerEvent::ClientDisconnected { id } => { println!("Client {} disconnected", id); } } } }); server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Video Playback / Gaming Encoding Strategy - RustVNC Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md For scenarios where speed and low latency are critical (like video playback or gaming), this strategy prioritizes fast encoding over high compression. Zlib (fast) is the primary choice, with Raw (absolute lowest latency) as a fallback. H.264 is noted as ideal but not yet implemented. ```text Primary: Zlib (fast) Reason: Speed > compression Low latency critical Fallback: Raw (absolute lowest latency) Note: H.264 would be ideal but not implemented ``` -------------------------------- ### Low-Bandwidth Encoding Strategy - RustVNC Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This configuration prioritizes compression for bandwidth-constrained links, accepting some quality loss. ZYWRLE (wavelet lossy) is the primary choice, with Tight (JPEG) as a secondary option and ZRLE as a fallback. ```text Primary: ZYWRLE (wavelet lossy) Reason: Best compression for bandwidth-constrained links Acceptable quality loss Secondary: Tight (JPEG) Fallback: ZRLE ``` -------------------------------- ### RustVNC Server Integration Dependency Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This TOML snippet shows how to add the RustVNC server as a dependency to another Rust project. It demonstrates both direct versioning and referencing the project from a Git repository. ```toml [dependencies] rustvncserver = "2.0" # Or from a git repository: # rustvncserver = { git = "https://github.com/dustinmcafee/rustvncserver" } ``` -------------------------------- ### RustVNC Server API Design Principles Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md Outlines the core API design principles and features offered by the RustVNC server library. ```APIDOC ## RustVNC Server API Design Principles ### Description The library provides a clean, modern API with full VNC protocol support, focusing on ease of use and performance. ### Core Features and API Methods | Feature | API Method | Notes | |----------------------|----------------------|-------------------------------------------| | Server initialization | `VncServer::new()` | Simple constructor | | Start server | `listen()` (async) | Tokio-based async I/O | | Framebuffer update | `update_framebuffer()` | Zero-copy updates | | Framebuffer resize | `resize_framebuffer()` | Dynamic resizing | | Reverse connection | `connect_reverse()` | Connect to viewer | | Repeater | `connect_repeater()` | UltraVNC Mode-2 | | CopyRect | `schedule_copy_rect()` | Efficient region copy | | Clipboard | Event-based | Via `ServerEvent` channel | ### API Design Principles - **Modern Rust API**: Leverages Rust's features for safety and concurrency. - **Async First**: Built on Tokio for non-blocking I/O operations. - **Zero-Copy Updates**: Optimizes framebuffer updates for performance. - **Full Protocol Support**: Implements a comprehensive subset of the VNC RFC 6143. ``` -------------------------------- ### VNC Client Structure and Methods (Rust) Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md Defines the VncClient structure, which holds state for an individual VNC client connection, including streams, framebuffer information, and compression settings. It includes asynchronous methods for handling client connections, sending framebuffer updates, and processing client messages. ```rust pub struct VncClient { client_id: usize, read_stream: OwnedReadHalf, write_stream: Arc>, framebuffer: Framebuffer, pixel_format: RwLock, encodings: RwLock>, jpeg_quality: AtomicU8, compression_level: AtomicU8, quality_level: AtomicU8, continuous_updates: AtomicBool, zlib_stream: RwLock>, tight_zlib_streams: RwLock, } impl VncClient { pub async fn handle_connection( socket: TcpStream, framebuffer: Arc>, client_id: usize ) -> Result<()>; pub async fn send_framebuffer_update(&mut self, regions: &[Rect]) -> Result<()>; pub async fn handle_client_message(&mut self) -> Result>; } ``` -------------------------------- ### Encoding Selection Logic in Rust Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md Implements the logic for selecting the preferred VNC encoding based on the client's offered list. It prioritizes encodings in the order they are provided by the client, defaulting to RAW if no other encoding is specified. ```rust // Encoding selection uses the first encoding from the client's list // Client sends encodings in preference order (highest priority first) let encodings = self.encodings.read().await; let preferred_encoding = encodings.first().copied().unwrap_or(ENCODING_RAW); ``` -------------------------------- ### RustVNC Server Cargo.toml Dependencies Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This TOML snippet lists the core dependencies for the RustVNC server, including crates for RFB encoding implementations, asynchronous runtime (Tokio), data handling (bytes), logging, error handling, encryption, and random number generation. ```toml [dependencies] rfb-encodings = "0.1" # RFB encoding implementations tokio = { version = "1", features = ["rt-multi-thread", "sync", "time", "net", "io-util", "macros"] } bytes = "1" log = "0.4" thiserror = "1.0" # Error handling des = "0.8" # DES encryption for VNC auth rand = "0.8" # Random number generation ``` -------------------------------- ### Enable Debug Logging - TOML Source: https://context7.com/rustvnc/rustvncserver/llms.txt This TOML snippet indicates the configuration for enabling debug logging, likely within a Cargo.toml file or a related configuration file, to facilitate troubleshooting and monitoring of VNC server operations and encoding statistics. ```toml ``` -------------------------------- ### Reverse Connection to VNC Viewer Source: https://github.com/rustvnc/rustvncserver/blob/main/README.md Initiates a reverse connection from the VNC server to a listening VNC viewer. This allows the server to connect to a viewer that might be behind a firewall or on a different network segment. ```rust // Connect to a listening viewer server.connect_reverse("192.168.1.100", 5500).await?; ``` -------------------------------- ### Manage Multiple Clients - Rust Source: https://context7.com/rustvnc/rustvncserver/llms.txt Handles multiple simultaneous VNC client connections, providing independent event streams for each. It tracks client connections and disconnections, and processes keyboard and pointer events. Requires a VncServer instance and tokio runtime. ```rust use rustvncserver::{VncServer, ServerEvent}; use std::collections::HashMap; #[tokio::main] async fn main() -> Result<(), Box> { let (server, mut events) = VncServer::new( 1280, 720, "Multi-Client Server".to_string(), Some("shared".to_string()), ); // Track connected clients let mut clients: HashMap = HashMap::new(); tokio::spawn(async move { while let Some(event) = events.recv().await { match event { ServerEvent::ClientConnected { id, address } => { let addr_str = address.to_string(); clients.insert(id, addr_str.clone()); println!("Client {} connected from {} (total: {})", id, addr_str, clients.len()); } ServerEvent::ClientDisconnected { id } => { if let Some(addr) = clients.remove(&id) { println!("Client {} ({}) disconnected (remaining: {})", id, addr, clients.len()); } } ServerEvent::KeyEvent { client_id, key, pressed } => { if pressed { println!("Client {} pressed key 0x{:X}", client_id, key); } } ServerEvent::PointerEvent { client_id, x, y, .. } => { println!("Client {} pointer at ({}, {})", client_id, x, y); } _ => {} } } }); // All clients share the same framebuffer // Updates are automatically sent to all connected clients server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### Configure Custom Pixel Format (Rust) Source: https://context7.com/rustvnc/rustvncserver/llms.txt Shows how to configure the pixel format for the VNC framebuffer. While the server uses RGBA32 internally, it can translate to various client-supported formats like RGB888, RGB565, or RGB555. RGBA32 is the default and recommended format. ```rust use rustvncserver::{VncServer, PixelFormat}; #[tokio::main] async fn main() -> Result<(), Box> { let (server, _events) = VncServer::new( 800, 600, "Custom Format".to_string(), None, ); // Server uses RGBA32 internally, but can translate to any client format // PixelFormat::rgba32() - 32-bit RGBA (default) // PixelFormat::rgb888() - 24-bit RGB // PixelFormat::rgb565() - 16-bit RGB // PixelFormat::rgb555() - 15-bit RGB let server_format = PixelFormat::rgba32(); println!("Server format: {}bpp, depth {}", server_format.bits_per_pixel, server_format.depth); // Create RGBA32 pixel data let pixels = vec![0u8; 800 * 600 * 4]; server .framebuffer() .update_cropped(&pixels, 0, 0, 800, 600) .await?; // Client can request any supported format during handshake // Server automatically translates RGBA32 to client format server.listen(5900).await?; Ok(()) } ``` -------------------------------- ### RustVNC VncServer Public API Structure Source: https://github.com/rustvnc/rustvncserver/blob/main/TECHNICAL.md This Rust code defines the structure of the `VncServer` and its associated public methods. It includes fields for managing the framebuffer, client connections, and server events, along with methods for listening on ports, connecting remotely, updating the framebuffer, resizing, and stopping the server. ```rust // Simplified structure - see actual code for complete implementation pub struct VncServer { framebuffer: Framebuffer, desktop_name: String, password: Option, clients: Arc>>>>, client_write_streams: Arc>>, client_tasks: Arc>>>, client_ids: Arc>>, event_tx: mpsc::UnboundedSender, // ... additional fields } impl VncServer { pub fn new(width: u16, height: u16) -> Self; pub async fn listen(&self, port: u16) -> Result<()>; pub async fn connect_reverse(&self, host: &str, port: u16) -> Result<()>; pub async fn connect_repeater(&self, host: &str, port: u16, id: &str) -> Result<()>; pub fn update_framebuffer(&self, data: &[u8], x: u16, y: u16, width: u16, height: u16); pub fn resize_framebuffer(&self, width: u16, height: u16); pub fn stop(&self); } ``` -------------------------------- ### RustVncServer Dependencies in Cargo.toml Source: https://context7.com/rustvnc/rustvncserver/llms.txt Specifies the necessary dependencies for the rustvncserver project, including the rustvncserver library itself with the 'debug-logging' feature enabled, and the env_logger crate for logging. ```toml [dependencies] rustvncserver = { version = "2.0", features = ["debug-logging"] } env_logger = "0.11" ```