use msgtrans::{
event::ClientEvent, protocol::TcpClientConfig, transport::client::TransportClientBuilder,
};
use std::time::Duration;
use tracing::{error, info, warn};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::DEBUG)
.init();
info!("[START] Starting TCP Echo client (simplified API - byte-only version)");
let tcp_config = TcpClientConfig::new("127.0.0.1:8001")?
.with_connect_timeout(Duration::from_secs(5))
.with_nodelay(true);
let mut transport = TransportClientBuilder::new()
.with_protocol(tcp_config)
.build()
.await?;
info!("[CONNECT] Connecting to TCP server...");
match transport.connect().await {
Ok(()) => {
info!("[SUCCESS] Connection successful!");
}
Err(e) => {
error!("[ERROR] Connection failed: {:?}", e);
return Err(e.into());
}
}
let mut event_stream = transport.subscribe_events();
let event_handle = tokio::spawn(async move {
info!("[START] Starting to listen for events...");
let mut event_count = 0;
while let Ok(event) = event_stream.recv().await {
event_count += 1;
match event {
ClientEvent::Connected { info } => {
info!("[CONNECT] Connection event: {:?}", info);
}
ClientEvent::MessageReceived(context) => {
info!(
"[RECV] Message received (ID: {}): {}",
context.message_id,
context.as_text_lossy()
);
if context.is_request() {
let message_id = context.message_id;
info!("[SEND] Responding to server request...");
context.respond(b"Hello from client response!".to_vec());
info!("[SUCCESS] Server request responded (ID: {})", message_id);
}
}
ClientEvent::MessageSent { message_id } => {
info!("[SUCCESS] Message sent successfully (ID: {})", message_id);
}
ClientEvent::Disconnected { reason } => {
warn!("[CLOSE] Connection disconnected: {:?}", reason);
break;
}
ClientEvent::Error { error } => {
error!("[ERROR] Transport error: {:?}", error);
break;
}
}
if event_count >= 15 {
info!("[STOP] Processed {} events, ending listening", event_count);
break;
}
}
});
info!("[SEND] Sending messages...");
let result1 = transport.send("Hello from TCP client!".as_bytes()).await?;
info!(
"[SUCCESS] Message sent successfully (ID: {})",
result1.message_id
);
let result2 = transport.send(b"Binary data from client").await?;
info!(
"[SUCCESS] Message sent successfully (ID: {})",
result2.message_id
);
tokio::time::sleep(Duration::from_millis(100)).await;
info!("[REQUEST] Sending request...");
match transport.request("What time is it?".as_bytes()).await {
Ok(result) => {
if let Some(response_data) = &result.data {
let response_text = String::from_utf8_lossy(response_data);
info!(
"[RECV] Response received (ID: {}): {}",
result.message_id, response_text
);
} else {
warn!(
"[WARN] Request result has no data (ID: {})",
result.message_id
);
}
}
Err(e) => {
warn!("[WARN] Request failed: {:?}", e);
}
}
match transport.request(b"Binary request").await {
Ok(result) => {
if let Some(response) = &result.data {
info!(
"[RECV] Binary response received (ID: {}): {} bytes",
result.message_id,
response.len()
);
if let Ok(text) = String::from_utf8(response.clone()) {
info!(" Content: {}", text);
}
} else {
warn!(
"[WARN] Binary request result has no data (ID: {})",
result.message_id
);
}
}
Err(e) => {
warn!("[WARN] Binary request failed: {:?}", e);
}
}
info!("[WAIT] Waiting for event processing to complete...");
let _ = tokio::time::timeout(Duration::from_secs(5), event_handle).await;
info!("[CLOSE] Disconnecting...");
transport.disconnect().await?;
info!("[STOP] TCP Echo client example completed");
Ok(())
}