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>
|
<p class="subtitle">Encrypted Voice</p>
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<label>Relay
|
<label>Relay
|
||||||
|
<div class="relay-row">
|
||||||
<input id="relay" type="text" value="193.180.213.68:4433" />
|
<input id="relay" type="text" value="193.180.213.68:4433" />
|
||||||
|
<span id="relay-status" class="relay-status"></span>
|
||||||
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<label>Room
|
<label>Room
|
||||||
<input id="room" type="text" value="android" />
|
<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.
|
/// 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),
|
/// The audio handle is only accessed from the thread that created it (drop),
|
||||||
/// never shared across threads — Sync is safe.
|
/// never shared across threads — Sync is safe.
|
||||||
|
#[allow(dead_code)]
|
||||||
struct SyncWrapper(Box<dyn std::any::Any + Send>);
|
struct SyncWrapper(Box<dyn std::any::Any + Send>);
|
||||||
unsafe impl Sync for SyncWrapper {}
|
unsafe impl Sync for SyncWrapper {}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,32 @@ struct AppState {
|
|||||||
engine: Mutex<Option<CallEngine>>,
|
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.
|
/// Read fingerprint from ~/.wzp/identity without connecting.
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn get_identity() -> Result<String, String> {
|
fn get_identity() -> Result<String, String> {
|
||||||
@@ -175,6 +201,7 @@ fn main() {
|
|||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.manage(state)
|
.manage(state)
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
ping_relay,
|
||||||
get_identity,
|
get_identity,
|
||||||
connect,
|
connect,
|
||||||
disconnect,
|
disconnect,
|
||||||
|
|||||||
@@ -126,6 +126,33 @@ function renderRecentRooms(rooms: RecentRoom[]) {
|
|||||||
|
|
||||||
applySettings();
|
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) ──
|
// ── Load fingerprint at startup (no connection needed) ──
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -89,6 +89,25 @@ body {
|
|||||||
border-color: var(--accent);
|
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 {
|
.form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|||||||
Reference in New Issue
Block a user