diff --git a/examples/client.rs b/examples/client.rs index 9e12a4a3..193d6894 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -4,6 +4,7 @@ use xmpp::jid::Jid; use xmpp::client::ClientBuilder; use xmpp::plugins::messaging::{MessagingPlugin, MessageEvent}; use xmpp::plugins::presence::{PresencePlugin, Show}; +use xmpp::plugins::ping::{PingPlugin, PingEvent}; use std::env; @@ -16,11 +17,16 @@ fn main() { .unwrap(); client.register_plugin(MessagingPlugin::new()); client.register_plugin(PresencePlugin::new()); + client.register_plugin(PingPlugin::new()); client.plugin::().set_presence(Show::Available, None).unwrap(); loop { let event = client.next_event().unwrap(); if let Some(evt) = event.downcast::() { println!("{:?}", evt); } + else if let Some(evt) = event.downcast::() { + println!("{:?}", evt); + client.plugin::().reply_ping(evt); + } } } diff --git a/src/ns.rs b/src/ns.rs index 4dce8aaa..24d27025 100644 --- a/src/ns.rs +++ b/src/ns.rs @@ -6,3 +6,4 @@ pub const TLS: &'static str = "urn:ietf:params:xml:ns:xmpp-tls"; pub const SASL: &'static str = "urn:ietf:params:xml:ns:xmpp-sasl"; pub const BIND: &'static str = "urn:ietf:params:xml:ns:xmpp-bind"; pub const STANZAS: &'static str = "urn:ietf:params:xml:ns:xmpp-stanzas"; +pub const PING: &'static str = "urn:xmpp:ping"; diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs index c15a923f..35e0f3bc 100644 --- a/src/plugins/mod.rs +++ b/src/plugins/mod.rs @@ -1,2 +1,3 @@ pub mod messaging; pub mod presence; +pub mod ping; diff --git a/src/plugins/ping.rs b/src/plugins/ping.rs new file mode 100644 index 00000000..e9a457c8 --- /dev/null +++ b/src/plugins/ping.rs @@ -0,0 +1,65 @@ +use plugin::{Plugin, PluginReturn, PluginProxy}; +use event::Event; +use minidom::Element; +use error::Error; +use jid::Jid; +use ns; + +#[derive(Debug)] +pub struct PingEvent { + pub from: Jid, + pub to: Jid, + pub id: String, +} + +impl Event for PingEvent {} + +pub struct PingPlugin { + proxy: PluginProxy, +} + +impl PingPlugin { + pub fn new() -> PingPlugin { + PingPlugin { + proxy: PluginProxy::new(), + } + } + + pub fn send_ping(&self, to: &Jid) -> Result<(), Error> { + let mut elem = Element::builder("iq") + .attr("type", "get") + .attr("to", to.to_string()) + .build(); + elem.append_child(Element::builder("ping").ns(ns::PING).build()); + self.proxy.send(elem); + Ok(()) + } + + pub fn reply_ping(&self, event: &PingEvent) { + let reply = Element::builder("iq") + .attr("type", "result") + .attr("to", event.from.to_string()) + .attr("id", event.id.to_string()) + .build(); + self.proxy.send(reply); + } +} + +impl Plugin for PingPlugin { + fn get_proxy(&mut self) -> &mut PluginProxy { + &mut self.proxy + } + + fn handle(&mut self, elem: &Element) -> PluginReturn { + if elem.is("iq", ns::CLIENT) && elem.attr("type") == Some("get") { + if elem.has_child("ping", ns::PING) { + self.proxy.dispatch(PingEvent { // TODO: safety!!! + from: elem.attr("from").unwrap().parse().unwrap(), + to: elem.attr("to").unwrap().parse().unwrap(), + id: elem.attr("id").unwrap().parse().unwrap(), + }); + } + } + PluginReturn::Continue + } +}