Skip to content

Commit

Permalink
Merge pull request #37 from luoqiz/feat-refactor
Browse files Browse the repository at this point in the history
优化、重构及添加多http回调功能
  • Loading branch information
lich0821 authored Oct 8, 2024
2 parents 1a465e2 + 2c74552 commit da300eb
Show file tree
Hide file tree
Showing 27 changed files with 469 additions and 99 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
"private": true,
"version": "0.0.1",
"scripts": {
"tauri dev": "cargo tauri dev",
"tauri build": "cargo tauri build",
"dev": "vite --mode dev",
"prod": "vite --mode prod",
"build": "vite build --mode prod",
"generate": "vite-ssg build",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit"
"typecheck": "vue-tsc --noEmit",
"i": "npm install"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@imengyu/vue3-context-menu": "^1.4.1",
"@tauri-apps/api": "^1.5.3",
"@types/qs": "^6.9.15",
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ winapi = { version = "0.3", features = [
tauri = { version = "1.6.1", features = ["api-all", "system-tray"] }
local-ip-address = "0.6.1"
uuid = { version = "1.2", features = ["v4"] }
async-trait = "0.1"
rand = "0.8.5"
ureq = { version = "2.10", features = ["json"] }

[features]
# this feature is used for production builds or when `devPath` points to the filesystem
Expand Down
1 change: 1 addition & 0 deletions src-tauri/config.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"cburl":["http://192.168.1.2:9999"],"wsurl":"","file_dir":""}
1 change: 0 additions & 1 deletion src-tauri/src/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use std::sync::{Arc, Mutex};
use std::thread::sleep;
use std::time::Duration;
use tokio::fs;
use tokio::io::AsyncWriteExt;
use utoipa::{IntoParams, OpenApi, ToSchema};
use utoipa_swagger_ui::Config;
use uuid::Uuid;
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/http_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ impl HttpServer {
}
}

pub fn start(&mut self, host: [u8; 4], port: u16, cburl: String) -> Result<(), String> {
let wechat = Arc::new(Mutex::new(WeChat::new(true, cburl)));
pub fn start(&mut self, host: [u8; 4], port: u16) -> Result<(), String> {
let wechat = Arc::new(Mutex::new(WeChat::new(true)));
self.wechat = Some(wechat.clone());
let (shutdown_tx, shutdown_rx) = oneshot::channel();
let addr = (host, port);
Expand Down
59 changes: 55 additions & 4 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
use chrono::Local;
use local_ip_address::local_ip;
use log::{info, Level, LevelFilter, Log, Metadata, Record};
use service::global_service::{initialize_global, GLOBAL};
use wechat_config::WechatConfig;
use std::fs::{self, File};
use std::io::Write;
use std::ptr;
use std::sync::{Arc, Mutex};
use tauri::{command, AppHandle, CustomMenuItem, Manager, SystemTray, SystemTrayMenu, WindowEvent};
Expand All @@ -18,6 +22,8 @@ use winapi::{
mod endpoints;
mod http_server;
mod wcferry;
mod service;
mod wechat_config;
use http_server::HttpServer;

struct FrontendLogger {
Expand Down Expand Up @@ -63,12 +69,51 @@ async fn is_http_server_running(
Ok(app_state.http_server_running)
}


// 写入配置到文件中
#[command]
fn save_wechat_config(
state: tauri::State<'_, Arc<Mutex<AppState>>>,
config: WechatConfig,
) -> Result<bool, String> {
// 定义文件路径
let file_path = ".\\config.json5";

// 尝试创建并写入文件
let mut file = File::create(&file_path).map_err(|e| e.to_string())?;
let json_str = serde_json::to_string(&config).unwrap();
file.write_all(json_str.as_bytes())
.map_err(|e| e.to_string())?;
let global = GLOBAL.get().unwrap();
let mut wechat_config_lock = global.wechat_config.try_lock().unwrap();
wechat_config_lock.cburl = config.cburl.clone();
wechat_config_lock.wsurl = config.wsurl.clone();
wechat_config_lock.file_dir = config.file_dir.clone();
info!("Wechat configuration update {:?}", serde_json::to_string(&config));
Ok(true)
}


// 读取文件
#[command]
fn read_wechat_config(state: tauri::State<'_, Arc<Mutex<AppState>>>) -> Result<WechatConfig, String> {
// 获取应用安装目录的路径
// let install_dir = resolve_path(&app, ".", None).map_err(|e| e.to_string())?;
// 定义文件路径
let file_path = ".\\config.json5";

// 尝试创建并写入文件
let file_str = fs::read_to_string(&file_path).unwrap();

let wechatconfig: WechatConfig = serde_json::from_str(&file_str).unwrap();
Ok(wechatconfig)
}

#[command]
async fn start_server(
state: tauri::State<'_, Arc<Mutex<AppState>>>,
host: String,
port: u16,
cburl: String,
) -> Result<(), String> {
let host_bytes = host
.split('.')
Expand All @@ -80,7 +125,7 @@ async fn start_server(
{
let mut app_state = state.inner().lock().unwrap();
if !app_state.http_server_running {
app_state.http_server.start(host_bytes, port, cburl)?;
app_state.http_server.start(host_bytes, port)?;
app_state.http_server_running = true;
}
}
Expand Down Expand Up @@ -119,6 +164,8 @@ async fn confirm_exit(app_handle: tauri::AppHandle) {
std::process::exit(0);
}



fn handle_system_tray_event(app_handle: &tauri::AppHandle, event: tauri::SystemTrayEvent) {
match event {
tauri::SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
Expand All @@ -143,7 +190,8 @@ fn init_log(handle: AppHandle) {
.expect("Failed to initialize logger");
}

fn main() {
#[tokio::main]
async fn main() {
let mutex_name = b"Global\\wcfrust_app_mutex\0";
unsafe {
let handle = CreateMutexA(ptr::null_mut(), 0, mutex_name.as_ptr() as *const i8);
Expand All @@ -170,6 +218,7 @@ fn main() {
.setup(|app| {
// init_window(app.get_window("main").unwrap());
init_log(app.app_handle());
initialize_global();
// app.get_window("main").unwrap().open_devtools();
Ok(())
})
Expand All @@ -193,7 +242,9 @@ fn main() {
stop_server,
confirm_exit,
is_http_server_running,
ip
ip,
save_wechat_config,
read_wechat_config
]);

app.run(tauri::generate_context!())
Expand Down
71 changes: 71 additions & 0 deletions src-tauri/src/service/global_service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::{fs, sync::{Arc, Mutex, OnceLock}};

use rand::Rng;

use crate::{service::message::{console_message_handler::ConsoleLogMessageHandler, http_message_handler::HttpMessageHandler, log_message_handler::LogMessageHandler}, wechat_config::WechatConfig};

use super::msg_event_mgr::MsgEventBus;


// 全局参数结构
pub struct GlobalState {
pub wechat_config: Arc<Mutex<WechatConfig>>,
pub msg_event_bus: Arc<Mutex<MsgEventBus>>,
}
// 全局变量
pub static GLOBAL: OnceLock<Arc<GlobalState>> = OnceLock::new();


// 初始化全局变量
pub fn initialize_global() {

// 初始化配置信息
let wechat_config: WechatConfig = init_config();

// 消息总线
let mut msg_event_bus = MsgEventBus::new();

log::info!("-------------------微信监听初始化--------------------------------");
let mut rng = rand::thread_rng();

// 前台日志处理器
let log_handler = Arc::new(LogMessageHandler {
id: rng.gen::<u32>().to_string(),
});
msg_event_bus.subscribe(log_handler);

// 控制台日志处理器
// let console_log_handler = Arc::new(ConsoleLogMessageHandler {
// id: rng.gen::<u32>().to_string(),
// });
// msg_event_bus.subscribe(console_log_handler);

// http 消息转发
let http_handler = Arc::new(HttpMessageHandler {
id: rng.gen::<u32>().to_string(),
});
msg_event_bus.subscribe(http_handler);

let msg_event_bus_arc = Arc::new(Mutex::new(msg_event_bus));

let global_state: GlobalState = GlobalState {
wechat_config: Arc::new(Mutex::new(wechat_config)),
msg_event_bus: msg_event_bus_arc,
};
let _ = GLOBAL.set(Arc::new(global_state));
}


// 读取配置
fn init_config() -> WechatConfig {
// 获取应用安装目录的路径
// let install_dir = resolve_path(&app, ".", None).map_err(|e| e.to_string())?;
// 定义文件路径
let file_path = ".\\config.json5";

// 尝试创建并写入文件
let file_str = fs::read_to_string(&file_path).unwrap();

let wechat_config: WechatConfig = serde_json::from_str(&file_str).unwrap();
wechat_config
}
20 changes: 20 additions & 0 deletions src-tauri/src/service/message/console_message_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use async_trait::async_trait;

use super::event_entity::{Event, EventHandler};

// 控制台日志打印
pub struct ConsoleLogMessageHandler {
pub id: String,
}

#[async_trait]
impl EventHandler for ConsoleLogMessageHandler {
async fn handle(&self, event: Event) {
if let Event::ClientMessage(ref msg) = event {
println!("控制台日志处理器 {} -- 接收到信息: {:?}", self.id, msg);
}
}
}



13 changes: 13 additions & 0 deletions src-tauri/src/service/message/event_entity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use async_trait::async_trait;

use crate::wcferry::wcf;

#[derive(Clone)]
pub enum Event {
ClientMessage(wcf::WxMsg),
}

#[async_trait]
pub trait EventHandler {
async fn handle(&self, event: Event);
}
47 changes: 47 additions & 0 deletions src-tauri/src/service/message/http_message_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use async_trait::async_trait;

use crate::service::global_service::GLOBAL;

use serde_json::json;

use super::event_entity::{Event, EventHandler};

/// 配置 http 回调地址后,将调用设置的url,
pub struct HttpMessageHandler {
pub id: String,
}

#[async_trait]
impl EventHandler for HttpMessageHandler {
async fn handle(&self, event: Event) {
if let Event::ClientMessage(ref msg) = event {
let global = GLOBAL.get().unwrap();
let k_config = global.wechat_config.try_lock().unwrap();
let cburl = k_config.cburl.clone();
if cburl.is_empty() {
return;
}

for url in cburl {
log::debug!("http服务 {} 回调地址为: {:?}", self.id, url.clone());
if !url.starts_with("http") {
log::error!("http 转发消息失败,回调地址不合法");
continue;
}

let res = ureq::post(&url).send_json(json!(&msg));
match res {
Ok(rsp) => {
if rsp.status() != 200 {
log::error!("转发消息失败,状态码: {}", rsp.status());
}
log::debug!("{}", rsp.into_string().unwrap());
}
Err(e) => {
log::error!("转发消息失败:{}", e);
}
}
}
}
}
}
20 changes: 20 additions & 0 deletions src-tauri/src/service/message/log_message_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use async_trait::async_trait;

use super::event_entity::{Event, EventHandler};

/// 日志打印
pub struct LogMessageHandler {
pub id: String,
}

#[async_trait]
impl EventHandler for LogMessageHandler {
async fn handle(&self, event: Event) {
if let Event::ClientMessage(ref msg) = event {
log::info!("日志处理器 {} -- 接收到信息: {:?}", self.id, msg);
}
}
}



4 changes: 4 additions & 0 deletions src-tauri/src/service/message/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod event_entity;
pub mod log_message_handler;
pub mod console_message_handler;
pub mod http_message_handler;
5 changes: 5 additions & 0 deletions src-tauri/src/service/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod global_service;
pub mod msg_event_mgr;
pub mod message;
// pub mod wechat_event_service;
// pub mod http_server_service;
Loading

0 comments on commit da300eb

Please sign in to comment.