From 68c9935823e2d0efedd1e0aaadea08f01144c06e Mon Sep 17 00:00:00 2001 From: Jasper Hugo Date: Sun, 6 Mar 2022 17:53:37 +0700 Subject: [PATCH] Implement XMPP pings (client -> server) --- lib-gst-meet/src/pinger.rs | 32 +++++++++++++++++++++++++---- lib-gst-meet/src/xmpp/connection.rs | 5 +---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib-gst-meet/src/pinger.rs b/lib-gst-meet/src/pinger.rs index 8e1e3d3..d084de0 100644 --- a/lib-gst-meet/src/pinger.rs +++ b/lib-gst-meet/src/pinger.rs @@ -1,16 +1,40 @@ -use std::convert::TryFrom; +use std::{convert::TryFrom, time::Duration}; use anyhow::{anyhow, Result}; use async_trait::async_trait; -use tokio::sync::mpsc; -use xmpp_parsers::{iq::Iq, Element, FullJid, Jid}; +use tokio::{sync::mpsc, task::JoinHandle, time}; +use tracing::warn; +use xmpp_parsers::{iq::Iq, Element, FullJid, Jid, ping::Ping}; -use crate::stanza_filter::StanzaFilter; +use crate::{stanza_filter::StanzaFilter, util::generate_id}; + +const PING_INTERVAL: Duration = Duration::from_secs(30); #[derive(Debug)] pub(crate) struct Pinger { pub(crate) jid: FullJid, pub(crate) tx: mpsc::Sender, + pub(crate) ping_task: JoinHandle<()>, +} + +impl Pinger { + pub(crate) fn new(jid: FullJid, tx: mpsc::Sender) -> Pinger { + let ping_tx = tx.clone(); + let ping_task = tokio::spawn(async move { + let mut interval = time::interval(PING_INTERVAL); + loop { + interval.tick().await; + if let Err(e) = ping_tx.send(Iq::from_get(generate_id(), Ping).into()).await { + warn!("failed to send XMPP ping: {:?}", e); + } + } + }); + Pinger { + jid, + tx, + ping_task, + } + } } #[async_trait] diff --git a/lib-gst-meet/src/xmpp/connection.rs b/lib-gst-meet/src/xmpp/connection.rs index 905ab77..d446103 100644 --- a/lib-gst-meet/src/xmpp/connection.rs +++ b/lib-gst-meet/src/xmpp/connection.rs @@ -269,10 +269,7 @@ impl Connection { info!("My JID: {}", jid); locked_inner.jid = Some(jid.clone()); - locked_inner.stanza_filters.push(Box::new(Pinger { - jid: jid.clone(), - tx: tx.clone(), - })); + locked_inner.stanza_filters.push(Box::new(Pinger::new(jid.clone(), tx.clone()))); let iq = Iq::from_get(generate_id(), DiscoInfoQuery { node: None }) .with_from(Jid::Full(jid.clone()))