#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Capture {
clear: bool, // ????????
interface: String, // ??
times: u64, // ??
}
pub async fn cmd_capture(
State(web_env): State<ArcWebEnv>,
Json(args): Json<Capture>,
) -> Result<impl IntoResponse, WebError> {
let env = web_env.env.lock().await;
let mac = env.conf.mac.clone().split(':').collect::<Vec<&str>>().join("");
let capture_status = env.capture_status.clone(); // shiyong suo
{
let mut cs = capture_status.lock().await;
info!("current upload status ={}", cs.uploading);
if args.clear && cs.uploading {
cs.sender
.try_send(())
.map_err(|e| {
warn!("Failed to send stop signal: {:?}", e);
e
})
.ok();
return Err(WebError::new(StatusCode::ACCEPTED, anyhow!("capture task has been cleared")));
}
if !args.clear && cs.uploading {
return Err(WebError::new(StatusCode::ACCEPTED, anyhow!("capture task is currently in progress. ignore")));
}
if args.clear && !cs.uploading {
return Err(WebError::new(StatusCode::ACCEPTED, anyhow!("capture task is not exist. ignore")));
}
let stop_rx = cs.rec.take().ok_or_else(|| {
WebError::new(StatusCode::ACCEPTED, anyhow!("capture task is currently in progressing. ignore"))
})?;
let capture_status_for_task = capture_status.clone();
let capture_task = start_capture_thread(capture_status_for_task, args.clone(), stop_rx, mac);
capture_task.await?;
}
Ok(())
}
注意一点:
不能删除take 这行代码。这行代码的作用是从 cs.rec
(类型为 Option<mpsc::Receiver<()>>
)中取出停止信号的接收端,并传递给 start_capture_thread
。由于 mpsc::Receiver
本身不可克隆,所以我们需要调用 .take()
将它的所有权转移出去。如果删除这行代码,就无法获取到 stop_rx
,也就失去了停止抓包任务的机制。