Comments (5)
Sure, you can do that. In the tcp-server.rs example, you just need to change server_context()
so that it creates an instance of the server state, and then pass that into the new_service
that's created.
This way, each client connection will create a new service (I think that's how tokio-modbus is designed) but all the services share a "state" value that's wrapped in an Arc<Mutex>
. I'd probably combine the holding registers and input registers HashMaps together into a single "state" struct, and the Mutex and Arc would wrap the entire state.
If that doesn't make sense, I could revise the example to demonstrate.
from tokio-modbus.
And, if you want to set the value in a separate thread or async task, you just need to pass an Arc<Mutex<ServerState>>
to that task and it can access the registers. For instance, we could maybe create a task that updates a timestamp register by incrementing it once per second.
from tokio-modbus.
Thank you @cdbennett for providing these helpful hints and proposals. These should be straightforward to implement.
I am closing this issue, because I don't see anything that the development team could do here.
@Ibens3C If you have managed to accomplish your task and want to improve the examples please share your knowledge by opening a pull/merge request.
from tokio-modbus.
Hi, I'm bit late to the discussion, but I have a very similar question.
Basically, I would like to change the tcp-server.rs example and add one more async task in select!
which would periodically update input registers in ExampleService
. How can I do it?
@cdbennett, you have suggested passing Arc<Mutex<ServerState>>
. Can you explain in more detail? Does ServerState
refers to a new struct or to ExampleService
? Should I define it early in the main
function and pass it to both update task and server_context
? What about new_service closure?
from tokio-modbus.
Ah, I got your your suggestion. Thanks!
For the reference, I defined
type Word = u16;
struct DataStore {
input_registers: HashMap<Address, Word>,
holding_registers: HashMap<Address, Word>,
}
struct ExampleService {
data_store: Arc<Mutex<DataStore>>,
}
I added one more argument data_store: &Arc<Mutex<DataStore>>
to server_context
and ExampleService::new
and fixed things accordingly. In particular
let new_service = |_socket_addr| Ok(Some(ExampleService::new(data_store.clone())));
The main
looks like this
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let socket_addr = "127.0.0.1:5502".parse().unwrap();
let data_store = Arc::new(Mutex::new(DataStore {
input_registers: HashMap::from([(0, 1234), (1, 5678)]),
holding_registers: HashMap::from([(0, 10), (1, 20), (2, 30), (3, 40)]),
}));
tokio::select! {
_ = server_context(socket_addr, &data_store) => unreachable!(),
_ = state_context(&data_store) => unreachable!(),
_ = client_context(socket_addr) => println!("Exiting"),
}
Ok(())
}
where state_context
is
async fn state_context(data_store: &Arc<Mutex<DataStore>>) {
let data_store = data_store.clone();
loop {
{
let input_registers = &mut data_store.lock().unwrap().input_registers;
*input_registers.get_mut(&0).unwrap() += 1;
}
tokio::time::sleep(Duration::from_millis(100)).await;
}
}
and client_context
makes repated request to input registers
// Read again
tokio::time::sleep(Duration::from_secs(1)).await;
let response = ctx.read_input_registers(0x00, 2).await.unwrap();
println!("CLIENT: The result is '{response:?}'");
from tokio-modbus.
Related Issues (20)
- TCP Sync Client HOT 8
- write_multiple_registers taking array as a param HOT 3
- Can not disconnect slave, need help HOT 3
- Although disconnect the context, the SerialStream reopen error HOT 1
- Patterns/best practice for reconnect-after-failure? HOT 1
- How to turn 'tokio_serial::SerialStream' into global static to save it for reuse
- is_connected()? HOT 1
- Modbus RTU - Serial Direction Pin HOT 6
- Dev Dependencies: Upgrade rustls-pemfile and tokio-rustls HOT 4
- Return Modbus exception codes for client and server.
- Use `async-trait` in `Service` trait ? HOT 10
- tokio-modbus 0.12 entering unreachable code in any response error HOT 7
- Dev Dependencies: Upgrade rustls
- How to get hexadecimal modbus rtu message data HOT 2
- Panic on unreachable code on disconnect HOT 3
- SECS/GEM SEMI? HOT 2
- Cant ignore Modbus RTU Request HOT 3
- Is it possible change trait Service to be a async trait? HOT 9
- rtu-server-address hangs HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tokio-modbus.