Files
tether/core/examples/progress_demo.rs
Patrick Ecord c9546ac222 core+apps: file transfer progress
Add a Transfer record {name, received, total, incoming, done} and an engine-side
transfers map updated by the RTC/LAN transports — fine-grained on receive (per
chunk in apply_file_frame), per-chunk on send. Engine.transfers() exposes
in-flight transfers (completed linger ~6s, then prune). Both apps poll it and
show a progress row with a bar + percent above the feed.

Verified with examples/progress_demo.rs: a 5MB file's transfer reports
received/total advancing to done.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 14:57:43 -05:00

45 lines
1.6 KiB
Rust

//! Sanity-check transfer progress: A sends a 5 MB file; poll B.transfers() and
//! A.transfers() to see received/total advance to done.
//! cargo run --example progress_demo
use std::time::Duration;
use tethercore::{Engine, Message, MessageHandler};
struct Noop;
impl MessageHandler for Noop {
fn on_message(&self, _m: Message) {}
fn on_status(&self, _c: bool) {}
fn on_file(&self, name: String, _mime: String, data: Vec<u8>) {
eprintln!(" received {name} ({} bytes)", data.len());
}
}
fn main() {
let dead = "http://127.0.0.1:1".to_string(); // LAN only
let room = "progress-room".to_string();
let payload = vec![9u8; 5_000_000];
let a = Engine::new(dead.clone(), room.clone(), "dev-a".into(), "macos".into(), "A".into(), "".into());
let b = Engine::new(dead, room, "dev-b".into(), "ios".into(), "B".into(), "".into());
a.start(Box::new(Noop));
b.start(Box::new(Noop));
eprintln!("waiting for LAN link…");
std::thread::sleep(Duration::from_secs(5));
a.send_file("big.bin".into(), "application/octet-stream".into(), payload);
for _ in 0..30 {
std::thread::sleep(Duration::from_millis(150));
let rx = b.transfers();
let tx = a.transfers();
if let Some(t) = rx.first() {
println!("↓ recv {}/{} {}", t.received, t.total, if t.done { "✅ done" } else { "" });
if t.done { break; }
} else if let Some(t) = tx.first() {
println!("↑ send {}/{} {}", t.received, t.total, if t.done { "done" } else { "" });
}
}
a.stop();
b.stop();
}