feat: mdns search.
This commit is contained in:
@ -110,7 +110,7 @@ impl LedColorsPublisher {
|
||||
tokio::spawn(async move {
|
||||
match Self::send_colors_by_display(colors, mappers).await {
|
||||
Ok(_) => {
|
||||
log::info!("sent colors: #{: >15}", display_id);
|
||||
// log::info!("sent colors: #{: >15}", display_id);
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Failed to send colors: #{: >15}\t{}", display_id, err);
|
||||
@ -328,12 +328,6 @@ impl LedColorsPublisher {
|
||||
tx_buffer.push((offset & 0xff) as u8);
|
||||
tx_buffer.append(&mut buffer);
|
||||
socket.send_to(&tx_buffer, "192.168.31.206:23042").await?;
|
||||
match Self::send_colors((group.start.min(group.end)) as u16, buffer).await {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
warn!("Failed to send colors: {}", err);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -11,7 +11,7 @@ mod screenshot_manager;
|
||||
use ambient_light::{Border, ColorCalibration, LedStripConfig, LedStripConfigGroup};
|
||||
use display_info::DisplayInfo;
|
||||
use paris::{error, info, warn};
|
||||
use rpc::MqttRpc;
|
||||
use rpc::{MqttRpc, UdpRpc};
|
||||
use screenshot::Screenshot;
|
||||
use screenshot_manager::ScreenshotManager;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -200,6 +200,8 @@ async fn main() {
|
||||
|
||||
let _mqtt = MqttRpc::global().await;
|
||||
|
||||
let _udp = UdpRpc::global().await;
|
||||
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
greet,
|
||||
|
8
src-tauri/src/rpc/board_info.rs
Normal file
8
src-tauri/src/rpc/board_info.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use std::net::{Ipv4Addr};
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct BoardInfo {
|
||||
pub name: String,
|
||||
pub address: Ipv4Addr,
|
||||
pub port: u16,
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
mod board_info;
|
||||
mod mqtt;
|
||||
mod udp;
|
||||
|
||||
pub use mqtt::*;
|
||||
pub use board_info::*;
|
||||
pub use mqtt::*;
|
||||
pub use udp::*;
|
||||
|
99
src-tauri/src/rpc/udp.rs
Normal file
99
src-tauri/src/rpc/udp.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use std::{collections::HashSet, sync::Arc, time::Duration};
|
||||
|
||||
use mdns_sd::{ServiceDaemon, ServiceEvent};
|
||||
use paris::{error, info, warn};
|
||||
use tokio::{
|
||||
net::UdpSocket,
|
||||
sync::{Mutex, OnceCell},
|
||||
};
|
||||
|
||||
use super::BoardInfo;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UdpRpc {
|
||||
socket: Arc<Mutex<UdpSocket>>,
|
||||
boards: Arc<Mutex<HashSet<BoardInfo>>>,
|
||||
}
|
||||
|
||||
impl UdpRpc {
|
||||
pub async fn global() -> &'static anyhow::Result<Self> {
|
||||
static UDP_RPC: OnceCell<anyhow::Result<UdpRpc>> = OnceCell::const_new();
|
||||
|
||||
UDP_RPC
|
||||
.get_or_init(|| async {
|
||||
let udp_rpc = UdpRpc::new().await?;
|
||||
udp_rpc.initialize().await;
|
||||
Ok(udp_rpc)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn new() -> anyhow::Result<Self> {
|
||||
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||
let socket = Arc::new(Mutex::new(socket));
|
||||
let boards = Arc::new(Mutex::new(HashSet::new()));
|
||||
Ok(Self { socket, boards })
|
||||
}
|
||||
|
||||
async fn initialize(&self) {
|
||||
let shared_self = Arc::new(self.clone());
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match shared_self.search_boards().await {
|
||||
Ok(_) => {
|
||||
info!("search_boards finished");
|
||||
}
|
||||
Err(err) => {
|
||||
error!("search_boards failed: {:?}", err);
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn search_boards(&self) -> anyhow::Result<()> {
|
||||
let mdns = ServiceDaemon::new()?;
|
||||
let shared_self = Arc::new(Mutex::new(self.clone()));
|
||||
|
||||
let service_type = "_ambient_light._udp.local.";
|
||||
|
||||
let receiver = mdns.browse(&service_type).map_err(|e| {
|
||||
warn!("Failed to browse for {:?}: {:?}", service_type, e);
|
||||
e
|
||||
})?;
|
||||
|
||||
while let Ok(event) = receiver.recv() {
|
||||
match event {
|
||||
ServiceEvent::ServiceResolved(info) => {
|
||||
info!(
|
||||
"Resolved a new service: {} host: {} port: {} IP: {:?} TXT properties: {:?}",
|
||||
info.get_fullname(),
|
||||
info.get_hostname(),
|
||||
info.get_port(),
|
||||
info.get_addresses(),
|
||||
info.get_properties(),
|
||||
);
|
||||
|
||||
let shared_self = shared_self.lock().await;
|
||||
let mut boards = shared_self.boards.clone().lock_owned().await;
|
||||
|
||||
let board = BoardInfo {
|
||||
name: info.get_fullname().to_string(),
|
||||
address: info.get_addresses().iter().next().unwrap().clone(),
|
||||
port: info.get_port(),
|
||||
};
|
||||
|
||||
if boards.insert(board.clone()) {
|
||||
info!("added board {:?}", board);
|
||||
}
|
||||
}
|
||||
other_event => {
|
||||
warn!("{:?}", &other_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user