diff --git a/client/src/app.rs b/client/src/app.rs index 36c3045..2b8acf6 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -52,6 +52,7 @@ impl LesavkaClientApp { pub async fn run(&mut self) -> Result<()> { /*────────── handshake / feature-negotiation ───────────────*/ + info!(server = %self.server_addr, "🚦 starting handshake"); let caps = handshake::negotiate(&self.server_addr).await; tracing::info!("🤝 server capabilities = {:?}", caps); @@ -70,6 +71,7 @@ impl LesavkaClientApp { /*────────── input aggregator task (grab after handshake) ─────────────*/ let mut aggregator = self.aggregator.take().expect("InputAggregator present"); + info!("⌛ grabbing input devices…"); aggregator.init()?; // grab devices now that handshake succeeded let agg_task = tokio::spawn(async move { let mut a = aggregator; diff --git a/client/src/handshake.rs b/client/src/handshake.rs index 190f4ac..ee44b86 100644 --- a/client/src/handshake.rs +++ b/client/src/handshake.rs @@ -1,8 +1,11 @@ // client/src/handshake.rs #![forbid(unsafe_code)] +use std::time::Duration; use lesavka_common::lesavka::{self as pb, handshake_client::HandshakeClient}; -use tonic::Code; +use tonic::{Code, transport::Endpoint}; +use tokio::time::timeout; +use tracing::{info, warn}; #[derive(Default, Clone, Copy, Debug)] pub struct PeerCaps { @@ -11,19 +14,41 @@ pub struct PeerCaps { } pub async fn negotiate(uri: &str) -> PeerCaps { - let mut cli = HandshakeClient::connect(uri.to_owned()) - .await - .expect("\"dial handshake\""); + info!(%uri, "🤝 dial handshake"); - match cli.get_capabilities(pb::Empty {}).await { + let ep = Endpoint::from_shared(uri.to_owned()) + .expect("handshake endpoint") + .tcp_nodelay(true) + .http2_keep_alive_interval(Duration::from_secs(15)) + .connect_timeout(Duration::from_secs(5)); + + let channel = timeout(Duration::from_secs(8), ep.connect()) + .await + .expect("handshake connect timeout") + .expect("handshake connect failed"); + + info!("🤝 handshake channel connected"); + let mut cli = HandshakeClient::new(channel); + info!("🤝 fetching capabilities…"); + + match timeout(Duration::from_secs(5), cli.get_capabilities(pb::Empty {})).await { + Ok(Ok(rsp)) => { + let caps = PeerCaps { + camera: rsp.get_ref().camera, + microphone: rsp.get_ref().microphone, + }; + info!(?caps, "🤝 handshake ok"); + caps + } Ok(rsp) => PeerCaps { camera: rsp.get_ref().camera, microphone: rsp.get_ref().microphone, }, - Err(e) if e.code() == Code::Unimplemented => { - // ↺ old server – pretend it supports nothing special. + Err(Err(e)) if e.code() == Code::Unimplemented => { + warn!("🤝 handshake not implemented on server – assuming defaults"); PeerCaps::default() } - Err(e) => panic!("\"handshake failed: {e}\""), + Err(Err(e)) => panic!("\"handshake failed: {e}\""), + Err(_) => panic!("handshake timed out"), } }