mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
a78b759741
This patch implement a restful server without any auth.
usage:
```bash
# run easytier-web, which acts as an gateway and registry for all easytier-core
$> easytier-web
# run easytier-core and connect to easytier-web with a token
$> easytier-core --config-server udp://127.0.0.1:22020/fdsafdsa
# use restful api to list session
$> curl -H "Content-Type: application/json" -X GET 127.0.0.1:11211/api/v1/sessions
[{"token":"fdsafdsa","client_url":"udp://127.0.0.1:48915","machine_id":"de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f"}]%
# use restful api to run a network instance
$> curl -H "Content-Type: application/json" -X POST 127.0.0.1:11211/api/v1/network/de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f -d '{"config": "listeners = [\"udp://0.0.0.0:12344\"]"}'
# use restful api to get network instance info
$> curl -H "Content-Type: application/json" -X GET 127.0.0.1:11211/api/v1/network/de3f5b8f-0f2f-d9d0-fb30-a2ac8951d92f/65437e50-b286-4098-a624-74429f2cb839
```
127 lines
3.5 KiB
Rust
127 lines
3.5 KiB
Rust
use std::sync::Arc;
|
|
|
|
use tokio::{
|
|
sync::{broadcast, Mutex},
|
|
task::JoinSet,
|
|
time::interval,
|
|
};
|
|
|
|
use crate::{
|
|
common::get_machine_id,
|
|
proto::{
|
|
rpc_impl::bidirect::BidirectRpcManager,
|
|
rpc_types::controller::BaseController,
|
|
web::{
|
|
HeartbeatRequest, HeartbeatResponse, WebClientServiceServer,
|
|
WebServerServiceClientFactory,
|
|
},
|
|
},
|
|
tunnel::Tunnel,
|
|
};
|
|
|
|
use super::controller::Controller;
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct HeartbeatCtx {
|
|
notifier: Arc<broadcast::Sender<HeartbeatResponse>>,
|
|
resp: Arc<Mutex<Option<HeartbeatResponse>>>,
|
|
}
|
|
|
|
pub struct Session {
|
|
rpc_mgr: BidirectRpcManager,
|
|
controller: Arc<Controller>,
|
|
|
|
heartbeat_ctx: HeartbeatCtx,
|
|
|
|
tasks: Mutex<JoinSet<()>>,
|
|
}
|
|
|
|
impl Session {
|
|
pub fn new(tunnel: Box<dyn Tunnel>, controller: Arc<Controller>) -> Self {
|
|
let rpc_mgr = BidirectRpcManager::new();
|
|
rpc_mgr.run_with_tunnel(tunnel);
|
|
|
|
rpc_mgr
|
|
.rpc_server()
|
|
.registry()
|
|
.register(WebClientServiceServer::new(controller.clone()), "");
|
|
|
|
let mut tasks: JoinSet<()> = JoinSet::new();
|
|
let heartbeat_ctx = Self::heartbeat_routine(&rpc_mgr, controller.token(), &mut tasks);
|
|
|
|
Session {
|
|
rpc_mgr,
|
|
controller,
|
|
heartbeat_ctx,
|
|
tasks: Mutex::new(tasks),
|
|
}
|
|
}
|
|
|
|
fn heartbeat_routine(
|
|
rpc_mgr: &BidirectRpcManager,
|
|
token: String,
|
|
tasks: &mut JoinSet<()>,
|
|
) -> HeartbeatCtx {
|
|
let (tx, _rx1) = broadcast::channel(2);
|
|
|
|
let ctx = HeartbeatCtx {
|
|
notifier: Arc::new(tx),
|
|
resp: Arc::new(Mutex::new(None)),
|
|
};
|
|
|
|
let mid = get_machine_id();
|
|
let inst_id = uuid::Uuid::new_v4();
|
|
let token = token;
|
|
|
|
let ctx_clone = ctx.clone();
|
|
let mut tick = interval(std::time::Duration::from_secs(1));
|
|
let client = rpc_mgr
|
|
.rpc_client()
|
|
.scoped_client::<WebServerServiceClientFactory<BaseController>>(1, 1, "".to_string());
|
|
tasks.spawn(async move {
|
|
let req = HeartbeatRequest {
|
|
machine_id: Some(mid.into()),
|
|
inst_id: Some(inst_id.into()),
|
|
user_token: token.to_string(),
|
|
};
|
|
loop {
|
|
tick.tick().await;
|
|
match client
|
|
.heartbeat(BaseController::default(), req.clone())
|
|
.await
|
|
{
|
|
Err(e) => {
|
|
tracing::error!("heartbeat failed: {:?}", e);
|
|
break;
|
|
}
|
|
Ok(resp) => {
|
|
tracing::debug!("heartbeat response: {:?}", resp);
|
|
let _ = ctx_clone.notifier.send(resp.clone());
|
|
ctx_clone.resp.lock().await.replace(resp);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
ctx
|
|
}
|
|
|
|
async fn wait_routines(&self) {
|
|
self.tasks.lock().await.join_next().await;
|
|
// if any task failed, we should abort all tasks
|
|
self.tasks.lock().await.abort_all();
|
|
}
|
|
|
|
pub async fn wait(&mut self) {
|
|
tokio::select! {
|
|
_ = self.rpc_mgr.wait() => {}
|
|
_ = self.wait_routines() => {}
|
|
}
|
|
}
|
|
|
|
pub async fn wait_next_heartbeat(&self) -> Option<HeartbeatResponse> {
|
|
let mut rx = self.heartbeat_ctx.notifier.subscribe();
|
|
rx.recv().await.ok()
|
|
}
|
|
}
|