Last active
October 8, 2022 01:16
-
-
Save susilolab/22641ef382e29d1203a1fcb06f35ec38 to your computer and use it in GitHub Desktop.
Windows service tcp server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::ffi::OsString; | |
| use std::env; | |
| use std::sync::{Arc, Mutex, mpsc}; | |
| use std::time::Duration; | |
| use tokio::{ | |
| net::TcpListener, | |
| io::{ | |
| AsyncReadExt, AsyncWriteExt | |
| }, | |
| }; | |
| use windows_service::service_control_handler::ServiceStatusHandle; | |
| use windows_service::{ | |
| service_dispatcher, | |
| define_windows_service, | |
| service::{ | |
| ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus, | |
| ServiceType, | |
| }, | |
| service_control_handler::{self, ServiceControlHandlerResult}, | |
| Result, | |
| }; | |
| const SERVICE_NAME: &str = "lisha_svc"; | |
| const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS; | |
| pub fn run() -> Result<()> { | |
| service_dispatcher::start(SERVICE_NAME, ffi_service_main) | |
| } | |
| define_windows_service!(ffi_service_main, lisha_service_main); | |
| pub fn lisha_service_main(arguments: Vec<OsString>) { | |
| if let Err(_e) = run_service() { | |
| } | |
| } | |
| pub fn run_service() -> Result<()> { | |
| let (shutdown_tx, shutdown_rx) = mpsc::channel(); | |
| let shared_status_handle: Arc<Mutex<Option<ServiceStatusHandle>>> = Arc::new(Mutex::new(None)); | |
| let cloned_status_handle = Arc::clone(&shared_status_handle); | |
| let event_handler = move |control_event| -> ServiceControlHandlerResult { | |
| match control_event { | |
| ServiceControl::Interrogate => ServiceControlHandlerResult::NoError, | |
| ServiceControl::Stop => { | |
| let status_handle = cloned_status_handle.lock().unwrap().unwrap(); | |
| shutdown_tx.send(()).unwrap(); | |
| ServiceControlHandlerResult::NoError | |
| } | |
| _ => ServiceControlHandlerResult::NotImplemented, | |
| } | |
| }; | |
| let status_handle = service_control_handler::register(SERVICE_NAME, event_handler)?; | |
| status_handle.set_service_status(ServiceStatus { | |
| service_type: SERVICE_TYPE, | |
| current_state: ServiceState::Running, | |
| controls_accepted: ServiceControlAccept::STOP, | |
| exit_code: ServiceExitCode::Win32(0), | |
| checkpoint: 0, | |
| wait_hint: tokio::time::Duration::default(), | |
| process_id: None, | |
| })?; | |
| let rt = tokio::runtime::Runtime::new().unwrap(); | |
| rt.block_on(async { | |
| env::set_var("RUST_LOG", "debug"); | |
| tracing_subscriber::fmt::init(); | |
| let listener = TcpListener::bind("127.0.0.1:4000").await.unwrap(); | |
| tracing::debug!("listening pada port 4000"); | |
| loop { | |
| let (mut socket,_) = listener.accept().await.unwrap(); | |
| match shutdown_rx.recv_timeout(Duration::from_secs(1)) { | |
| Ok(_) | Err(mpsc::RecvTimeoutError::Disconnected) => break, | |
| Err(mpsc::RecvTimeoutError::Timeout) => (), | |
| } | |
| tokio::spawn(async move { | |
| let mut buf = [0; 1024]; | |
| loop { | |
| let n = match socket.read(&mut buf).await { | |
| Ok(n) if n == 0 => return, | |
| Ok(n) => n, | |
| Err(e) => { | |
| eprintln!("Gagal membaca dari socket; err = {:?}", e); | |
| return; | |
| } | |
| }; | |
| println!("data: {:?}", &buf[0..n]); | |
| tracing::debug!("data: {:?}", &buf[0..n]); | |
| if let Err(e) = socket.write_all(&buf[0..n]).await { | |
| eprintln!("Gagal menulis ke socket; err = {:?}", e); | |
| return; | |
| } | |
| } | |
| }); | |
| } | |
| }); | |
| status_handle.set_service_status(ServiceStatus { | |
| service_type: SERVICE_TYPE, | |
| current_state: ServiceState::Stopped, | |
| controls_accepted: ServiceControlAccept::empty(), | |
| exit_code: ServiceExitCode::Win32(0), | |
| checkpoint: 0, | |
| wait_hint: tokio::time::Duration::default(), | |
| process_id: None, | |
| })?; | |
| Ok(()) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment