CLI Server mode: resolve DNS, start HTTP, loop
(port: u16, interval_minutes: u32, template: Option<String>)
| 123 | |
| 124 | /// CLI Server mode: resolve DNS, start HTTP, loop |
| 125 | async fn run_server_cli(port: u16, interval_minutes: u32, template: Option<String>) { |
| 126 | println!("🌐 服务端模式启动"); |
| 127 | println!(" 监听端口: {}", port); |
| 128 | println!(" 更新间隔: {} 分钟", interval_minutes); |
| 129 | if let Some(ref tpl) = template { |
| 130 | println!(" HTML模板: {}", tpl); |
| 131 | // Update config so generate_server_html picks up the template |
| 132 | let mut cfg = config::load_config(); |
| 133 | cfg.server.template_path = tpl.clone(); |
| 134 | let _ = config::save_config(&cfg); |
| 135 | } |
| 136 | println!(); |
| 137 | |
| 138 | // Initial DNS resolve |
| 139 | cli_log("开始解析 GitHub DNS..."); |
| 140 | match services::server_fetch_hosts().await { |
| 141 | Ok(_) => cli_log("✅ 解析 Github DNS 成功!"), |
| 142 | Err(e) => cli_log(&format!("❌ 解析 Github DNS 失败: {}", e)), |
| 143 | } |
| 144 | |
| 145 | // Start HTTP server |
| 146 | let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(false); |
| 147 | let shutdown_tx_signal = shutdown_tx.clone(); |
| 148 | |
| 149 | let http_handle = tokio::spawn(async move { |
| 150 | start_cli_http_server(port, shutdown_rx).await; |
| 151 | }); |
| 152 | |
| 153 | // Handle Ctrl+C |
| 154 | tokio::spawn(async move { |
| 155 | let _ = tokio::signal::ctrl_c().await; |
| 156 | let _ = shutdown_tx_signal.send(true); |
| 157 | }); |
| 158 | |
| 159 | cli_log(&format!("✅ HTTP 服务已启动: http://127.0.0.1:{}", port)); |
| 160 | cli_log(&format!(" hosts.txt → http://127.0.0.1:{}/hosts.txt", port)); |
| 161 | cli_log(&format!(" hosts.json → http://127.0.0.1:{}/hosts.json", port)); |
| 162 | |
| 163 | let interval = std::time::Duration::from_secs(interval_minutes as u64 * 60); |
| 164 | let mut interval_timer = tokio::time::interval(interval); |
| 165 | interval_timer.tick().await; // skip first tick |
| 166 | |
| 167 | let mut shutdown_main = shutdown_tx.subscribe(); |
| 168 | |
| 169 | loop { |
| 170 | tokio::select! { |
| 171 | _ = interval_timer.tick() => { |
| 172 | cli_log("开始解析 GitHub DNS..."); |
| 173 | match services::server_fetch_hosts().await { |
| 174 | Ok(_) => cli_log("✅ 解析 Github DNS 成功!"), |
| 175 | Err(e) => cli_log(&format!("❌ 解析 Github DNS 失败: {}", e)), |
| 176 | } |
| 177 | } |
| 178 | _ = shutdown_main.changed() => { |
| 179 | cli_log("🛑 收到停止信号,正在退出..."); |
| 180 | let _ = shutdown_tx.send(true); |
| 181 | let _ = tokio::time::timeout( |
| 182 | std::time::Duration::from_secs(3), |
no test coverage detected