feat: 通过新的 udp 逻辑发送灯带颜色。

This commit is contained in:
Ivan Li 2023-04-29 18:07:21 +08:00
parent f6e3257670
commit 11045f27d8
4 changed files with 44 additions and 10 deletions

1
src-tauri/Cargo.lock generated
View File

@ -2913,6 +2913,7 @@ dependencies = [
"core-graphics", "core-graphics",
"display-info", "display-info",
"env_logger", "env_logger",
"futures",
"hex", "hex",
"itertools", "itertools",
"log", "log",

View File

@ -34,6 +34,7 @@ itertools = "0.10.5"
core-foundation = "0.9.3" core-foundation = "0.9.3"
tokio-stream = "0.1.14" tokio-stream = "0.1.14"
mdns-sd = "0.7.2" mdns-sd = "0.7.2"
futures = "0.3.28"
[features] [features]
# this feature is used for production builds or when `devPath` points to the filesystem # this feature is used for production builds or when `devPath` points to the filesystem

View File

@ -12,7 +12,7 @@ use crate::{
ambient_light::{config, ConfigManager}, ambient_light::{config, ConfigManager},
led_color::LedColor, led_color::LedColor,
screenshot::LedSamplePoints, screenshot::LedSamplePoints,
screenshot_manager::{self, ScreenshotManager}, screenshot_manager::{self, ScreenshotManager}, rpc::UdpRpc,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -292,7 +292,13 @@ impl LedColorsPublisher {
.min() .min()
.unwrap(); .unwrap();
let socket = UdpSocket::bind("0.0.0.0:0").await?; let udp_rpc = UdpRpc::global().await;
if let Err(err) = udp_rpc {
warn!("udp_rpc can not be initialized: {}", err);
}
let udp_rpc = udp_rpc.as_ref().unwrap();
// let socket = UdpSocket::bind("0.0.0.0:0").await?;
for group in mappers.clone() { for group in mappers.clone() {
if (group.start.abs_diff(group.end)) > colors.len() { if (group.start.abs_diff(group.end)) > colors.len() {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
@ -327,7 +333,8 @@ impl LedColorsPublisher {
tx_buffer.push((offset >> 8) as u8); tx_buffer.push((offset >> 8) as u8);
tx_buffer.push((offset & 0xff) as u8); tx_buffer.push((offset & 0xff) as u8);
tx_buffer.append(&mut buffer); tx_buffer.append(&mut buffer);
socket.send_to(&tx_buffer, "192.168.31.206:23042").await?;
udp_rpc.send_to_all(&tx_buffer).await?;
} }
Ok(()) Ok(())

View File

@ -1,18 +1,20 @@
use std::{collections::HashSet, sync::Arc, time::Duration}; use std::{collections::HashSet, sync::Arc, time::Duration};
use futures::future::join_all;
use itertools::Itertools;
use mdns_sd::{ServiceDaemon, ServiceEvent}; use mdns_sd::{ServiceDaemon, ServiceEvent};
use paris::{error, info, warn}; use paris::{error, info, warn};
use tokio::{ use tokio::{
net::UdpSocket, net::UdpSocket,
sync::{watch, Mutex, OnceCell}, sync::{watch, Mutex, OnceCell, RwLock},
}; };
use super::BoardInfo; use super::BoardInfo;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UdpRpc { pub struct UdpRpc {
socket: Arc<Mutex<UdpSocket>>, socket: Arc<UdpSocket>,
boards: Arc<Mutex<HashSet<BoardInfo>>>, boards: Arc<RwLock<HashSet<BoardInfo>>>,
boards_change_sender: Arc<Mutex<watch::Sender<HashSet<BoardInfo>>>>, boards_change_sender: Arc<Mutex<watch::Sender<HashSet<BoardInfo>>>>,
boards_change_receiver: Arc<Mutex<watch::Receiver<HashSet<BoardInfo>>>>, boards_change_receiver: Arc<Mutex<watch::Receiver<HashSet<BoardInfo>>>>,
} }
@ -32,8 +34,8 @@ impl UdpRpc {
async fn new() -> anyhow::Result<Self> { async fn new() -> anyhow::Result<Self> {
let socket = UdpSocket::bind("0.0.0.0:0").await?; let socket = UdpSocket::bind("0.0.0.0:0").await?;
let socket = Arc::new(Mutex::new(socket)); let socket = Arc::new(socket);
let boards = Arc::new(Mutex::new(HashSet::new())); let boards = Arc::new(RwLock::new(HashSet::new()));
let (boards_change_sender, boards_change_receiver) = watch::channel(HashSet::new()); let (boards_change_sender, boards_change_receiver) = watch::channel(HashSet::new());
let boards_change_sender = Arc::new(Mutex::new(boards_change_sender)); let boards_change_sender = Arc::new(Mutex::new(boards_change_sender));
let boards_change_receiver = Arc::new(Mutex::new(boards_change_receiver)); let boards_change_receiver = Arc::new(Mutex::new(boards_change_receiver));
@ -84,7 +86,7 @@ impl UdpRpc {
); );
let shared_self = shared_self.lock().await; let shared_self = shared_self.lock().await;
let mut boards = shared_self.boards.clone().lock_owned().await; let mut boards = shared_self.boards.write().await;
let board = BoardInfo { let board = BoardInfo {
name: info.get_fullname().to_string(), name: info.get_fullname().to_string(),
@ -116,7 +118,30 @@ impl UdpRpc {
} }
pub async fn get_boards(&self) -> HashSet<BoardInfo> { pub async fn get_boards(&self) -> HashSet<BoardInfo> {
let boards = self.boards.clone().lock_owned().await; let boards = self.boards.read().await;
boards.clone() boards.clone()
} }
pub async fn send_to_all(&self, buff: &Vec<u8>) -> anyhow::Result<()> {
let boards = self.get_boards().await;
let socket = self.socket.clone();
let handlers = boards.into_iter()
.map(|board| {
let socket = socket.clone();
let buff = buff.clone();
tokio::spawn(async move {
match socket.send_to(&buff, (board.address, board.port)).await {
Ok(_) => {},
Err(err) => {
error!("failed to send to {}: {:?}", board.name, err);
},
}
})
});
join_all(handlers).await;
Ok(())
}
} }