Skip to main content

pub_node/
pub_node.rs

1use std::path::Path;
2use std::sync::Arc;
3use std::thread;
4use std::time::Duration;
5
6use serde::Deserialize;
7
8use rs_ctrl_os::{
9    config::ConfigManager, init_logging, start_discovery, PubSubManager, Result, TimeSynchronizer,
10};
11
12#[derive(Clone, Deserialize)]
13struct DynamicCfg {
14    message_prefix: String,
15    interval_ms: u64,
16}
17
18fn main() -> Result<()> {
19    init_logging();
20
21    let config_path = std::env::args()
22        .nth(1)
23        .unwrap_or_else(|| "pub_config.toml".to_string());
24
25    let manager: ConfigManager<DynamicCfg> = ConfigManager::new(Path::new(&config_path))?;
26    let static_cfg = manager.static_cfg().clone();
27
28    // Time synchronizer for this node (acts as master in this simple setup)
29    let time_sync = Arc::new(TimeSynchronizer::new());
30
31    // Start discovery so other nodes can find us; we also get a live registry back.
32    let registry = start_discovery(
33        &static_cfg.my_id,
34        &static_cfg.host,
35        static_cfg.port,
36        static_cfg.is_master,
37        Some(time_sync.clone()),
38    )?;
39
40    // Publisher only: one PUB socket for topic "control"
41    // 频率由 static_config 的 publish_hz/subscribe_hz 提供,new() 时已注入
42    let mut bus = PubSubManager::new(&static_cfg, registry)?;
43
44    loop {
45        let dyn_cfg = manager.get_dynamic_clone();
46        let ts_ms = time_sync.now_corrected_ms();
47
48        let payload = format!(
49            "{} from {} at {} ms",
50            dyn_cfg.message_prefix, static_cfg.my_id, ts_ms
51        );
52
53        // Single pub: topic key "control", sub-topic "demo"
54        bus.publish_topic("control", "demo", &payload)?;
55
56        thread::sleep(Duration::from_millis(dyn_cfg.interval_ms));
57    }
58}