use std::io::{Read, Write};
use std::net::TcpStream;
use crate::error::Result;
use crate::protocol::any_message::AnyMessage;
use crate::protocol::factory::MessageFactory;
use crate::protocol::header::Header;
use crate::protocol::message::{IgtlMessage, Message};
use tracing::{debug, info, trace};
pub struct SyncTcpClient {
stream: TcpStream,
verify_crc: bool,
}
impl SyncTcpClient {
pub fn connect(addr: &str) -> Result<Self> {
info!("Connecting to {}", addr);
let stream = TcpStream::connect(addr)?;
debug!("Connected to {}", addr);
Ok(SyncTcpClient {
stream,
verify_crc: true,
})
}
pub fn set_verify_crc(&mut self, verify: bool) {
self.verify_crc = verify;
}
pub fn verify_crc(&self) -> bool {
self.verify_crc
}
pub fn set_read_timeout(&self, timeout: Option<std::time::Duration>) -> Result<()> {
self.stream.set_read_timeout(timeout)?;
Ok(())
}
pub fn set_write_timeout(&self, timeout: Option<std::time::Duration>) -> Result<()> {
self.stream.set_write_timeout(timeout)?;
Ok(())
}
pub fn send<T: Message>(&mut self, msg: &IgtlMessage<T>) -> Result<()> {
let data = msg.encode()?;
trace!("Sending {} bytes", data.len());
self.stream.write_all(&data)?;
self.stream.flush()?;
debug!("Sent {} bytes", data.len());
Ok(())
}
pub fn receive<T: Message>(&mut self) -> Result<IgtlMessage<T>> {
let mut header_buf = [0u8; 58];
self.stream.read_exact(&mut header_buf)?;
let header = Header::decode(&header_buf)?;
debug!("Received header: size={}", header.body_size);
let body_size = header.body_size as usize;
let mut body_buf = vec![0u8; body_size];
self.stream.read_exact(&mut body_buf)?;
let mut full_msg = header_buf.to_vec();
full_msg.extend_from_slice(&body_buf);
let result = IgtlMessage::decode_with_options(&full_msg, self.verify_crc);
match &result {
Ok(_msg) => {
trace!("Successfully decoded message");
}
Err(e) => {
debug!("Failed to decode message: {}", e);
}
}
result
}
pub fn receive_any(&mut self) -> Result<AnyMessage> {
let mut header_buf = [0u8; Header::SIZE];
self.stream.read_exact(&mut header_buf)?;
let header = Header::decode(&header_buf)?;
debug!(
"Received header: type={}, device={}, size={}",
header.type_name.as_str().unwrap_or("?"),
header.device_name.as_str().unwrap_or("?"),
header.body_size
);
let body_size = header.body_size as usize;
let mut body_buf = vec![0u8; body_size];
self.stream.read_exact(&mut body_buf)?;
let factory = MessageFactory::new();
let result = factory.decode_any(&header, &body_buf, self.verify_crc);
match &result {
Ok(msg) => {
trace!("Successfully decoded {} message", msg.message_type());
}
Err(e) => {
debug!("Failed to decode message: {}", e);
}
}
result
}
}