diff --git a/tokio-xmpp/Cargo.toml b/tokio-xmpp/Cargo.toml index cd3420fe432ef487de4031b6c365f207aeda98e6..31cf17bcbff865a719785731a54ef6c15d54e6e2 100644 --- a/tokio-xmpp/Cargo.toml +++ b/tokio-xmpp/Cargo.toml @@ -40,7 +40,7 @@ ktls = { version = "6", optional = true } [dev-dependencies] env_logger = { version = "0.11", default-features = false, features = ["auto-color", "humantime"] } # this is needed for echo-component example -tokio = { version = "1", features = ["test-util"] } +tokio = { version = "1", features = ["signal", "test-util"] } tokio-xmpp = { path = ".", features = ["insecure-tcp"]} [features] diff --git a/tokio-xmpp/examples/keep_connection.rs b/tokio-xmpp/examples/keep_connection.rs new file mode 100644 index 0000000000000000000000000000000000000000..a37fda19ea1a70d9500c756437cd086a0f832e59 --- /dev/null +++ b/tokio-xmpp/examples/keep_connection.rs @@ -0,0 +1,83 @@ +// Copyright (c) 2024 Jonas Schäfer +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//! Keep a connection alive +//! +//! This example demonstrates that tokio_xmpp will keep a connection alive +//! as good as it can, transparently reconnecting on interruptions of the TCP +//! stream. + +use std::env::args; +use std::process::exit; +use std::str::FromStr; +use std::time::Duration; + +use rand::{thread_rng, Rng}; + +use futures::StreamExt; + +use tokio_xmpp::{ + connect::{DnsConfig, StartTlsServerConnector}, + parsers::{ + iq::Iq, + jid::{BareJid, Jid}, + ping, + }, + stanzastream::StanzaStream, + xmlstream::Timeouts, +}; + +#[tokio::main] +async fn main() { + env_logger::init(); + + let args: Vec = args().collect(); + if args.len() != 3 { + println!("Usage: {} ", args[0]); + exit(1); + } + let jid = BareJid::from_str(&args[1]).expect(&format!("Invalid JID: {}", &args[1])); + let password = &args[2]; + + let mut timeouts = Timeouts::tight(); + timeouts.read_timeout = Duration::new(5, 0); + + let mut stream = StanzaStream::new_c2s( + StartTlsServerConnector::from(DnsConfig::UseSrv { + host: jid.domain().as_str().to_owned(), + srv: "_xmpp-client._tcp".to_owned(), + fallback_port: 5222, + }), + jid.clone().into(), + password.clone(), + timeouts, + 16, + ); + let domain: Jid = jid.domain().to_owned().into(); + let mut ping_timer = tokio::time::interval(Duration::new(5, 0)); + let mut ping_ctr: u64 = thread_rng().gen(); + let signal = tokio::signal::ctrl_c(); + tokio::pin!(signal); + loop { + tokio::select! { + _ = &mut signal => { + log::info!("Ctrl+C pressed, shutting down cleanly."); + break; + } + _ = ping_timer.tick() => { + log::info!("sending ping for fun & profit"); + ping_ctr = ping_ctr.wrapping_add(1); + let mut iq = Iq::from_get(format!("ping-{}", ping_ctr), ping::Ping); + iq.to = Some(domain.clone()); + stream.send(Box::new(iq.into())).await; + } + ev = stream.next() => { + log::info!("{:?}", ev); + } + } + } + stream.close().await; +}