impl internal Event enum, resubscribe if broker restarts

This commit is contained in:
Evan Feenstra
2022-06-12 11:19:06 -07:00
parent a1ecd05526
commit 94f9f8d733
3 changed files with 74 additions and 54 deletions

View File

@@ -16,9 +16,9 @@ const SUB_TOPIC: &str = "sphinx-return";
const PUB_TOPIC: &str = "sphinx";
const USERNAME: &str = "sphinx-key";
const PASSWORD: &str = "sphinx-key-pass";
// must get a reply within this time, or disconnects
const REPLY_TIMEOUT_MS: u64 = 1000;
// static CONNECTED: OnceCell<bool> = OnceCell::new();
static CONNECTED: SyncLazy<Mutex<bool>> = SyncLazy::new(|| Mutex::new(false));
fn set_connected(b: bool) {
*CONNECTED.lock().unwrap() = b;
@@ -41,9 +41,6 @@ pub fn start_broker(
router.start().expect("could not start router");
});
// let mut client_connected = AtomicBool::new(false);
// CONNECTED.set(false).expect("could init CONNECTED");
let mut rt_builder = tokio::runtime::Builder::new_multi_thread();
rt_builder.enable_all();
let rt = rt_builder.build().unwrap();
@@ -167,7 +164,7 @@ fn config() -> Config {
};
let mut servers = HashMap::new();
servers.insert(
"0".to_string(),
id.to_string(),
ServerSettings {
cert: None,
listen: SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 1883).into(),

View File

@@ -1,10 +1,11 @@
use crate::core::events::Event as CoreEvent;
use embedded_svc::mqtt::client::utils::ConnState;
use embedded_svc::mqtt::client::{Client, Connection, MessageImpl, Publish, QoS, Event, Message as MqttMessage};
use embedded_svc::mqtt::client::{Connection, MessageImpl, QoS, Event, Message as MqttMessage};
use embedded_svc::mqtt::client::utils::Connection as MqttConnection;
use esp_idf_svc::mqtt::client::*;
use anyhow::Result;
use log::*;
use std::time::Duration;
use std::thread;
use esp_idf_sys::{self};
use esp_idf_sys::EspError;
@@ -15,6 +16,7 @@ pub const TOPIC: &str = "sphinx";
pub const RETURN_TOPIC: &str = "sphinx-return";
pub const USERNAME: &str = "sphinx-key";
pub const PASSWORD: &str = "sphinx-key-pass";
pub const QOS: QoS = QoS::AtMostOnce;
pub fn make_client(broker: &str, client_id: &str) -> Result<(
EspMqttClient<ConnState<MessageImpl, EspError>>,
@@ -33,32 +35,20 @@ pub fn make_client(broker: &str, client_id: &str) -> Result<(
let b = format!("mqtt://{}", broker);
// let (mut client, mut connection) = EspMqttClient::new_with_conn(b, &conf)?;
let cc = loop {
let broker_url = b.clone();
info!("===> CONNECT TO {}", &broker_url);
match EspMqttClient::new_with_conn(broker_url, &conf) {
Ok(c_c) => {
info!("EspMqttClient::new_with_conn finished");
break c_c
},
Err(_) => {
thread::sleep(Duration::from_secs(1));
}
}
};
//
let cc = EspMqttClient::new_with_conn(b, &conf)?;
info!("MQTT client started");
Ok(cc)
}
pub fn start_listening(
mut client: EspMqttClient<ConnState<MessageImpl, EspError>>,
client: EspMqttClient<ConnState<MessageImpl, EspError>>,
mut connection: MqttConnection<Condvar, MessageImpl, EspError>,
tx: mpsc::Sender<Vec<u8>>,
tx: mpsc::Sender<CoreEvent>,
) -> Result<EspMqttClient<ConnState<MessageImpl, EspError>>> {
// must start pumping before subscribe or publish will work
// must start pumping before subscribe or publish will not work
thread::spawn(move || {
info!("MQTT Listening for messages");
loop {
@@ -73,20 +63,20 @@ pub fn start_listening(
},
Ok(msg) => {
match msg {
Event::BeforeConnect => info!("RECEIVED BEFORE CONNECT MESSAGE"),
Event::Connected(flag) => {
if flag {
info!("RECEIVED CONNECTED = TRUE MESSAGE");
} else {
info!("RECEIVED CONNECTED = FALSE MESSAGE");
}
Event::BeforeConnect => info!("RECEIVED BeforeConnect MESSAGE"),
Event::Connected(_flag) => {
info!("RECEIVED Connected MESSAGE");
tx.send(CoreEvent::Connected).expect("couldnt send Event::Connected");
},
Event::Disconnected => warn!("RECEIVED DISCONNECTION MESSAGE"),
Event::Subscribed(_mes_id) => info!("RECEIVED SUBSCRIBED MESSAGE"),
Event::Unsubscribed(_mes_id) => info!("RECEIVED UNSUBSCRIBED MESSAGE"),
Event::Published(_mes_id) => info!("RECEIVED PUBLISHED MESSAGE"),
Event::Received(msg) => tx.send(msg.data().to_vec()).expect("could send to TX"),
Event::Deleted(_mes_id) => info!("RECEIVED DELETED MESSAGE"),
Event::Disconnected => {
warn!("RECEIVED Disconnected MESSAGE");
tx.send(CoreEvent::Disconnected).expect("couldnt send Event::Disconnected");
},
Event::Subscribed(_mes_id) => info!("RECEIVED Subscribed MESSAGE"),
Event::Unsubscribed(_mes_id) => info!("RECEIVED Unsubscribed MESSAGE"),
Event::Published(_mes_id) => info!("RECEIVED Published MESSAGE"),
Event::Received(msg) => tx.send(CoreEvent::Message(msg.data().to_vec())).expect("couldnt send Event::Message"),
Event::Deleted(_mes_id) => info!("RECEIVED Deleted MESSAGE"),
}
},
}
@@ -97,8 +87,8 @@ pub fn start_listening(
//info!("MQTT connection loop exit");
});
log::info!("SUBSCRIBE TO {}", TOPIC);
client.subscribe(TOPIC, QoS::AtMostOnce)?;
// log::info!("SUBSCRIBE TO {}", TOPIC);
// client.subscribe(TOPIC, QoS::AtMostOnce)?;
Ok(client)
}

View File

@@ -1,43 +1,76 @@
use crate::conn::mqtt::RETURN_TOPIC;
use crate::conn::mqtt::{RETURN_TOPIC, TOPIC, QOS};
use sphinx_key_signer::{self, InitResponse, PubKey};
use std::sync::mpsc;
use esp_idf_sys;
use embedded_svc::mqtt::client::Client;
use embedded_svc::httpd::Result;
use embedded_svc::mqtt::client::utils::ConnState;
use embedded_svc::mqtt::client::{MessageImpl, Publish, QoS};
use embedded_svc::mqtt::client::{MessageImpl, Publish};
use esp_idf_svc::mqtt::client::*;
use esp_idf_sys::EspError;
use log::*;
pub enum Event {
Connected,
Disconnected,
Message(Vec<u8>)
}
#[cfg(not(feature = "pingpong"))]
pub fn make_event_loop(mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>, rx: mpsc::Receiver<Vec<u8>>) -> Result<()> {
pub fn make_event_loop(mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>, rx: mpsc::Receiver<Event>) -> Result<()> {
// initialize the RootHandler
let init_msg_bytes = rx.recv().expect("NO INIT MSG");
let InitResponse { root_handler, init_reply } = sphinx_key_signer::init(init_msg_bytes).expect("failed to init signer");
mqtt.publish(RETURN_TOPIC, QoS::AtMostOnce, false, init_reply).expect("could not publish init response");
let root_handler = while let Ok(event) = rx.recv() {
if let Event::Message(msg_bytes) = event {
let InitResponse { root_handler, init_reply } = sphinx_key_signer::init(event.clone()).expect("failed to init signer");
mqtt.publish(RETURN_TOPIC, QOS, false, init_reply).expect("could not publish init response");
break root_handler
}
};
// signing loop
let dummy_peer = PubKey([0; 33]);
while let Ok(msg_bytes) = rx.recv() {
let _ret = match sphinx_key_signer::handle(&root_handler, msg_bytes, dummy_peer.clone()) {
Ok(b) => mqtt.publish(RETURN_TOPIC, QoS::AtMostOnce, false, b).expect("could not publish init response"),
Err(e) => panic!("HANDLE FAILED {:?}", e),
};
match event {
Event::Connected => {
log::info!("SUBSCRIBE TO {}", TOPIC);
mqtt.subscribe(TOPIC, QOS).expect("could not MQTT subscribe");
},
Event::Message(ref msg_bytes) => {
let _ret = match sphinx_key_signer::handle(&root_handler, msg_bytes.clone(), dummy_peer.clone()) {
Ok(b) => mqtt.publish(RETURN_TOPIC, QOS, false, b).expect("could not publish init response"),
Err(e) => panic!("HANDLE FAILED {:?}", e),
};
},
Event::Disconnected => {
log::info!("GOT A Event::Disconnected msg!");
}
}
}
Ok(())
}
#[cfg(feature = "pingpong")]
pub fn make_event_loop(mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>, rx: mpsc::Receiver<Vec<u8>>) -> Result<()> {
pub fn make_event_loop(mut mqtt: EspMqttClient<ConnState<MessageImpl, EspError>>, rx: mpsc::Receiver<Event>) -> Result<()> {
info!("About to subscribe to the mpsc channel");
while let Ok(msg_bytes) = rx.recv() {
let b = sphinx_key_signer::parse_ping_and_form_response(msg_bytes);
log::info!("GOT A PING MESSAGE! returning pong now...");
mqtt.publish(RETURN_TOPIC, QoS::AtMostOnce, false, b).expect("could not publish init response");
while let Ok(event) = rx.recv() {
match event {
Event::Connected => {
log::info!("SUBSCRIBE TO {}", TOPIC);
mqtt.subscribe(TOPIC, QOS).expect("could not MQTT subscribe");
},
Event::Message(msg_bytes) => {
let b = sphinx_key_signer::parse_ping_and_form_response(msg_bytes);
log::info!("GOT A PING MESSAGE! returning pong now...");
mqtt.publish(RETURN_TOPIC, QOS, false, b).expect("could not publish init response");
},
Event::Disconnected => {
log::info!("GOT A Event::Disconnected msg!");
}
}
}
Ok(())