feat: relay ping with RTT display, fix dead_code warning
Some checks failed
Build Release Binaries / build-amd64 (push) Has been cancelled
Some checks failed
Build Release Binaries / build-amd64 (push) Has been cancelled
- New ping_relay Tauri command: QUIC connect with 3s timeout, returns RTT ms - Relay status shown next to input field: "42ms" (green) or "offline" (red) - Auto-pings on app startup and debounced on relay input change - Fix SyncWrapper dead_code warning with #[allow(dead_code)] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,10 @@
|
||||
<p class="subtitle">Encrypted Voice</p>
|
||||
<div class="form">
|
||||
<label>Relay
|
||||
<input id="relay" type="text" value="193.180.213.68:4433" />
|
||||
<div class="relay-row">
|
||||
<input id="relay" type="text" value="193.180.213.68:4433" />
|
||||
<span id="relay-status" class="relay-status"></span>
|
||||
</div>
|
||||
</label>
|
||||
<label>Room
|
||||
<input id="room" type="text" value="android" />
|
||||
|
||||
@@ -18,6 +18,7 @@ const FRAME_SAMPLES: usize = 960;
|
||||
/// Wrapper to make non-Sync audio handles safe to store in shared state.
|
||||
/// The audio handle is only accessed from the thread that created it (drop),
|
||||
/// never shared across threads — Sync is safe.
|
||||
#[allow(dead_code)]
|
||||
struct SyncWrapper(Box<dyn std::any::Any + Send>);
|
||||
unsafe impl Sync for SyncWrapper {}
|
||||
|
||||
|
||||
@@ -37,6 +37,32 @@ struct AppState {
|
||||
engine: Mutex<Option<CallEngine>>,
|
||||
}
|
||||
|
||||
/// Ping a relay to check if it's online and measure RTT.
|
||||
#[tauri::command]
|
||||
async fn ping_relay(relay: String) -> Result<u32, String> {
|
||||
let addr: std::net::SocketAddr = relay.parse().map_err(|e| format!("bad address: {e}"))?;
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
let bind: std::net::SocketAddr = "0.0.0.0:0".parse().unwrap();
|
||||
let endpoint = wzp_transport::create_endpoint(bind, None).map_err(|e| format!("{e}"))?;
|
||||
let client_cfg = wzp_transport::client_config();
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
match tokio::time::timeout(
|
||||
std::time::Duration::from_secs(3),
|
||||
wzp_transport::connect(&endpoint, addr, "ping", client_cfg),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Ok(conn)) => {
|
||||
let rtt_ms = start.elapsed().as_millis() as u32;
|
||||
conn.close(0u32.into(), b"ping");
|
||||
Ok(rtt_ms)
|
||||
}
|
||||
Ok(Err(e)) => Err(format!("{e}")),
|
||||
Err(_) => Err("timeout (3s)".into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Read fingerprint from ~/.wzp/identity without connecting.
|
||||
#[tauri::command]
|
||||
fn get_identity() -> Result<String, String> {
|
||||
@@ -175,6 +201,7 @@ fn main() {
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.manage(state)
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
ping_relay,
|
||||
get_identity,
|
||||
connect,
|
||||
disconnect,
|
||||
|
||||
@@ -126,6 +126,33 @@ function renderRecentRooms(rooms: RecentRoom[]) {
|
||||
|
||||
applySettings();
|
||||
|
||||
// ── Relay ping ──
|
||||
const relayStatusEl = document.getElementById("relay-status")!;
|
||||
let pingDebounce: number | null = null;
|
||||
|
||||
async function pingRelay(address: string) {
|
||||
relayStatusEl.textContent = "...";
|
||||
relayStatusEl.className = "relay-status pinging";
|
||||
try {
|
||||
const rtt: number = await invoke("ping_relay", { relay: address });
|
||||
relayStatusEl.textContent = `${rtt}ms`;
|
||||
relayStatusEl.className = "relay-status online";
|
||||
connectBtn.disabled = false;
|
||||
} catch {
|
||||
relayStatusEl.textContent = "offline";
|
||||
relayStatusEl.className = "relay-status offline";
|
||||
}
|
||||
}
|
||||
|
||||
// Ping on load and when relay input changes
|
||||
relayInput.addEventListener("input", () => {
|
||||
if (pingDebounce) clearTimeout(pingDebounce);
|
||||
pingDebounce = window.setTimeout(() => pingRelay(relayInput.value), 500);
|
||||
});
|
||||
|
||||
// Initial ping
|
||||
setTimeout(() => pingRelay(relayInput.value), 300);
|
||||
|
||||
// ── Load fingerprint at startup (no connection needed) ──
|
||||
(async () => {
|
||||
try {
|
||||
|
||||
@@ -89,6 +89,25 @@ body {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.relay-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.relay-row input { flex: 1; }
|
||||
|
||||
.relay-status {
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
min-width: 50px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.relay-status.online { color: var(--green); }
|
||||
.relay-status.offline { color: var(--red); }
|
||||
.relay-status.pinging { color: var(--text-dim); }
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
Reference in New Issue
Block a user