use super::*;
use std::ops::Deref;
pub struct AsyncTcpClient<const N: usize = 9> {
core: AsyncClientCore,
}
impl<const N: usize> Deref for AsyncTcpClient<N> {
type Target = AsyncClientCore;
fn deref(&self) -> &Self::Target {
&self.core
}
}
impl AsyncTcpClient<9> {
#[cfg(feature = "tcp")]
#[deprecated(note = "use AsyncTcpClient::new(...) and then client.connect().await")]
pub fn connect(host: &str, port: u16) -> Result<Self, AsyncError> {
Self::new(host, port)
}
#[cfg(feature = "tcp")]
#[deprecated(
note = "use AsyncTcpClient::new_with_poll_interval(...) and then client.connect().await"
)]
pub fn connect_with_poll_interval(
host: &str,
port: u16,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_with_poll_interval(host, port, poll_interval)
}
#[cfg(feature = "tcp")]
pub fn new(host: &str, port: u16) -> Result<Self, AsyncError> {
Self::new_with_pipeline(host, port)
}
#[cfg(feature = "tcp")]
pub fn new_with_poll_interval(
host: &str,
port: u16,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_with_pipeline_and_poll_interval(host, port, poll_interval)
}
}
impl<const N: usize> AsyncTcpClient<N> {
#[cfg(feature = "tcp")]
#[deprecated(
note = "use AsyncTcpClient::new_with_pipeline(...) and then client.connect().await"
)]
pub fn connect_with_pipeline(host: &str, port: u16) -> Result<Self, AsyncError> {
Self::new_with_pipeline(host, port)
}
#[cfg(feature = "tcp")]
#[deprecated(
note = "use AsyncTcpClient::new_with_pipeline_and_poll_interval(...) and then client.connect().await"
)]
pub fn connect_with_pipeline_and_poll_interval(
host: &str,
port: u16,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
Self::new_with_pipeline_and_poll_interval(host, port, poll_interval)
}
#[cfg(feature = "tcp")]
pub fn new_with_pipeline(host: &str, port: u16) -> Result<Self, AsyncError> {
let transport = StdTcpTransport::new();
let config = ModbusConfig::Tcp(ModbusTcpConfig::new(host, port)?);
Self::from_transport_config(transport, config, Duration::from_millis(20))
}
#[cfg(feature = "tcp")]
pub fn new_with_pipeline_and_poll_interval(
host: &str,
port: u16,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
let transport = StdTcpTransport::new();
let config = ModbusConfig::Tcp(ModbusTcpConfig::new(host, port)?);
Self::from_transport_config(transport, config, poll_interval)
}
#[cfg(feature = "tcp")]
fn from_transport_config(
transport: StdTcpTransport,
config: ModbusConfig,
poll_interval: Duration,
) -> Result<Self, AsyncError> {
let pending = Arc::new(Mutex::new(HashMap::new()));
#[cfg(feature = "traffic")]
let traffic_handler = Arc::new(Mutex::new(None));
#[cfg(feature = "traffic")]
let (traffic_sender, traffic_receiver) = mpsc::channel();
let app = AsyncApp {
pending: pending.clone(),
#[cfg(feature = "traffic")]
traffic_sender,
};
let client = ClientServices::<_, _, N>::new(transport, app, config)?;
let (sender, receiver) = mpsc::channel();
thread::spawn(move || run_worker(client, pending, receiver, poll_interval));
#[cfg(feature = "traffic")]
{
let dispatcher_handler = traffic_handler.clone();
thread::spawn(move || run_traffic_dispatcher(traffic_receiver, dispatcher_handler));
}
#[cfg(feature = "traffic")]
{
return Ok(Self {
core: AsyncClientCore::new(sender, traffic_handler),
});
}
#[cfg(not(feature = "traffic"))]
{
Ok(Self {
core: AsyncClientCore::new(sender),
})
}
}
}