mbus_async/runtime/
network_client.rs1use super::*;
9use std::ops::Deref;
10
11pub struct AsyncTcpClient<const N: usize = 9> {
20 core: AsyncClientCore,
21}
22
23impl<const N: usize> Deref for AsyncTcpClient<N> {
24 type Target = AsyncClientCore;
25
26 fn deref(&self) -> &Self::Target {
27 &self.core
28 }
29}
30
31impl AsyncTcpClient<9> {
34 #[cfg(feature = "tcp")]
38 #[deprecated(note = "use AsyncTcpClient::new(...) and then client.connect().await")]
39 pub fn connect(host: &str, port: u16) -> Result<Self, AsyncError> {
40 Self::new(host, port)
41 }
42
43 #[cfg(feature = "tcp")]
48 #[deprecated(
49 note = "use AsyncTcpClient::new_with_poll_interval(...) and then client.connect().await"
50 )]
51 pub fn connect_with_poll_interval(
52 host: &str,
53 port: u16,
54 poll_interval: Duration,
55 ) -> Result<Self, AsyncError> {
56 Self::new_with_poll_interval(host, port, poll_interval)
57 }
58
59 #[cfg(feature = "tcp")]
65 pub fn new(host: &str, port: u16) -> Result<Self, AsyncError> {
66 Self::new_with_pipeline(host, port)
67 }
68
69 #[cfg(feature = "tcp")]
75 pub fn new_with_poll_interval(
76 host: &str,
77 port: u16,
78 poll_interval: Duration,
79 ) -> Result<Self, AsyncError> {
80 Self::new_with_pipeline_and_poll_interval(host, port, poll_interval)
81 }
82
83 #[cfg(feature = "tcp")]
92 pub fn new_with_config(
93 tcp_config: ModbusTcpConfig,
94 poll_interval: Duration,
95 ) -> Result<Self, AsyncError> {
96 let transport = StdTcpTransport::new();
97 Self::from_transport_config(transport, ModbusConfig::Tcp(tcp_config), poll_interval)
98 }
99}
100
101impl<const N: usize> AsyncTcpClient<N> {
104 #[cfg(feature = "tcp")]
109 #[deprecated(
110 note = "use AsyncTcpClient::new_with_pipeline(...) and then client.connect().await"
111 )]
112 pub fn connect_with_pipeline(host: &str, port: u16) -> Result<Self, AsyncError> {
113 Self::new_with_pipeline(host, port)
114 }
115
116 #[cfg(feature = "tcp")]
121 #[deprecated(
122 note = "use AsyncTcpClient::new_with_pipeline_and_poll_interval(...) and then client.connect().await"
123 )]
124 pub fn connect_with_pipeline_and_poll_interval(
125 host: &str,
126 port: u16,
127 poll_interval: Duration,
128 ) -> Result<Self, AsyncError> {
129 Self::new_with_pipeline_and_poll_interval(host, port, poll_interval)
130 }
131
132 #[cfg(feature = "tcp")]
137 pub fn new_with_pipeline(host: &str, port: u16) -> Result<Self, AsyncError> {
138 let transport = StdTcpTransport::new();
139 let config = ModbusConfig::Tcp(ModbusTcpConfig::new(host, port)?);
140 Self::from_transport_config(transport, config, Duration::from_millis(20))
141 }
142
143 #[cfg(feature = "tcp")]
149 pub fn new_with_pipeline_and_poll_interval(
150 host: &str,
151 port: u16,
152 poll_interval: Duration,
153 ) -> Result<Self, AsyncError> {
154 let transport = StdTcpTransport::new();
155 let config = ModbusConfig::Tcp(ModbusTcpConfig::new(host, port)?);
156 Self::from_transport_config(transport, config, poll_interval)
157 }
158
159 #[cfg(feature = "tcp")]
169 pub fn new_with_config_and_pipeline(
170 tcp_config: ModbusTcpConfig,
171 poll_interval: Duration,
172 ) -> Result<Self, AsyncError> {
173 let transport = StdTcpTransport::new();
174 Self::from_transport_config(transport, ModbusConfig::Tcp(tcp_config), poll_interval)
175 }
176
177 #[cfg(feature = "tcp")]
181 fn from_transport_config(
182 transport: StdTcpTransport,
183 config: ModbusConfig,
184 poll_interval: Duration,
185 ) -> Result<Self, AsyncError> {
186 let pending = Arc::new(Mutex::new(HashMap::new()));
187 #[cfg(feature = "traffic")]
188 let traffic_handler = Arc::new(Mutex::new(None));
189 #[cfg(feature = "traffic")]
190 let (traffic_sender, traffic_receiver) = mpsc::channel();
191 let app = AsyncApp {
192 pending: pending.clone(),
193 #[cfg(feature = "traffic")]
194 traffic_sender,
195 };
196
197 let client = ClientServices::<_, _, N>::new(transport, app, config)?;
198 let (sender, receiver) = mpsc::channel();
199
200 thread::spawn(move || run_worker(client, pending, receiver, poll_interval));
201 #[cfg(feature = "traffic")]
202 {
203 let dispatcher_handler = traffic_handler.clone();
204 thread::spawn(move || run_traffic_dispatcher(traffic_receiver, dispatcher_handler));
205 }
206
207 #[cfg(feature = "traffic")]
208 {
209 Ok(Self {
210 core: AsyncClientCore::new(sender, traffic_handler),
211 })
212 }
213
214 #[cfg(not(feature = "traffic"))]
215 {
216 Ok(Self {
217 core: AsyncClientCore::new(sender),
218 })
219 }
220 }
221}