diff --git a/src/core/entity/mod.rs b/src/core/entity/mod.rs index b28e9d9..3678007 100644 --- a/src/core/entity/mod.rs +++ b/src/core/entity/mod.rs @@ -1,4 +1,3 @@ -use crate::cipher::Aes256GcmCipher; use chrono::{DateTime, Local}; use std::collections::HashMap; use std::net::{Ipv4Addr, SocketAddr}; @@ -37,12 +36,14 @@ impl NetworkInfo { pub struct ClientInfo { // 设备ID pub device_id: String, + // 版本 + pub version: String, // 名称 pub name: String, // 客户端间是否加密 pub client_secret: bool, - // 和服务端的加密方式 - pub server_secret: Option, + // 和服务端是否加密 + pub server_secret: bool, // 链接服务器的来源地址 pub address: SocketAddr, // 是否在线 @@ -52,20 +53,23 @@ pub struct ClientInfo { // 建立的tcp连接发送端 pub tcp_sender: Option>>, pub client_status: Option, + pub last_join_time: DateTime, } impl Default for ClientInfo { fn default() -> Self { Self { device_id: "".to_string(), + version: "".to_string(), name: "".to_string(), client_secret: false, - server_secret: None, + server_secret: false, address: "0.0.0.0:0".parse().unwrap(), online: false, virtual_ip: 0, tcp_sender: None, client_status: None, + last_join_time: Local::now(), } } } diff --git a/src/core/server/web/mod.rs b/src/core/server/web/mod.rs index c2fc965..51cb2e4 100644 --- a/src/core/server/web/mod.rs +++ b/src/core/server/web/mod.rs @@ -98,7 +98,7 @@ pub async fn start( .service(group_info) .service(Files::new("/", "./static/").index_file("index.html")) }) - .listen(lst)? - .run() - .await + .listen(lst)? + .run() + .await } diff --git a/src/core/server/web/service/mod.rs b/src/core/server/web/service/mod.rs index a9b10bd..589cf85 100644 --- a/src/core/server/web/service/mod.rs +++ b/src/core/server/web/service/mod.rs @@ -99,13 +99,15 @@ impl VntsWebService { let client_info = ClientInfo { device_id: into.device_id.clone(), + version: into.version.clone(), name: into.name.clone(), client_secret: into.client_secret, - server_secret: into.server_secret.is_some(), + server_secret: into.server_secret, address, online: into.online, virtual_ip: into.virtual_ip.into(), status_info, + last_join_time: into.last_join_time.format("%Y-%m-%d %H:%M:%S").to_string(), }; network.clients.push(client_info); } diff --git a/src/core/server/web/vo/mod.rs b/src/core/server/web/vo/mod.rs index 917ff99..2afa366 100644 --- a/src/core/server/web/vo/mod.rs +++ b/src/core/server/web/vo/mod.rs @@ -43,6 +43,8 @@ impl ResponseMessage> { pub struct ClientInfo { // 设备ID pub device_id: String, + // 客户端版本 + pub version: String, // 名称 pub name: String, // 客户端间是否加密 @@ -56,6 +58,7 @@ pub struct ClientInfo { // 分配的ip pub virtual_ip: Ipv4Addr, pub status_info: Option, + pub last_join_time: String, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/main.rs b/src/main.rs index 77f4a57..5cb9bd7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ use std::io::Write; use std::net::Ipv4Addr; use std::path::PathBuf; -// use crate::service::{start_tcp, start_udp}; use clap::Parser; use crate::cipher::RsaCipher; diff --git a/static/index.html b/static/index.html index ac0f2f7..bccaab4 100644 --- a/static/index.html +++ b/static/index.html @@ -236,7 +236,10 @@ } let node = { clientName: client.name, - natType: status_info.is_cone ? '锥形' : '对称', + clientVersion: client.version, + deviceId: client.device_id, + lastJoinTime: client.last_join_time, + natType: status_info.is_cone == null ? '' : (status_info.is_cone ? '锥形' : '对称'), upStream: formatBytes(status_info.up_stream), downStream: formatBytes(status_info.down_stream), clientSecret: client.client_secret, diff --git a/static/js/group-node.js b/static/js/group-node.js index 1c09bd4..d16d140 100644 --- a/static/js/group-node.js +++ b/static/js/group-node.js @@ -422,6 +422,11 @@ G6.registerNode('card-node', { afterDraw: nodeBasicMethod.afterDraw, setState: nodeBasicMethod.setState, }); + +function toString(v) { + return v ? v : '' +} + const tooltip = new G6.Tooltip({ offsetX: 70, offsetY: 20, @@ -430,11 +435,14 @@ const tooltip = new G6.Tooltip({ // outDiv.style.width = '180px' outDiv.innerHTML = `
    -
  • 名称: ${e.item.getModel().clientName}
  • -
  • IP: ${e.item.getModel().ip}
  • -
  • NAT类型: ${e.item.getModel().natType}
  • -
  • 上传: ${e.item.getModel().upStream}
  • -
  • 下载: ${e.item.getModel().downStream}
  • +
  • 名称: ${toString(e.item.getModel().clientName)}
  • +
  • ID: ${toString(e.item.getModel().deviceId)}
  • +
  • 版本: ${toString(e.item.getModel().clientVersion)}
  • +
  • IP: ${toString(e.item.getModel().ip)}
  • +
  • 上传: ${toString(e.item.getModel().upStream)}
  • +
  • 下载: ${toString(e.item.getModel().downStream)}
  • +
  • NAT类型: ${toString(e.item.getModel().natType)}
  • +
  • 注册时间: ${toString(e.item.getModel().lastJoinTime)}
` return outDiv },