10 releases (5 breaking)
0.6.0 | Apr 10, 2019 |
---|---|
0.5.1 | Mar 31, 2019 |
0.4.0 | Jan 6, 2019 |
0.3.3 | Dec 31, 2018 |
0.1.0 | Aug 15, 2018 |
#1118 in Encoding
Used in remote-hal
51KB
879 lines
Rust Daemon
A library to simplify communication with daemons in rust, with the goal of hiding as much of the complexity of / minimizing the effort required to use tokio as much as possible.
This consists of a higher-level generic server and connection object to provide typed communication between components, implemented using tokio using codecs. This is designed to support arbitrary stream types, and both types have been implemented over TCPStream
and UnixStream
for convenience. If you find any other useful stream types to wrap, please open an issue or a PR!
A generic example codec is provided using serde and serde_json to establish a type-safe json interface for client-daemon communication, when using this codec the ENC
and DEC
types must implement serde Serialize
and Deserialize
traits, these may be implemented using serde_derive. It is intended that additional codecs will be added as they are required.
Status
Usage
See src/examples/server.rs and src/examples/connection.rs for an example server and client implementing a simple key-value store.
You can build these examples with cargo build --features examples
, run the server with ./targets/debug/rustd-server
and interact using ./targets/debug/rustd-client
. rustd-client -k KEY
fetches the value for a given key, rustd-client -k KEY -v VALUE
sets the value of the given key, and rustd-client --help
will display available arguments.
Client
extern crate daemon_engine;
use daemon_engine::Connection;
...
// Create client instance
let stream = UnixStream::connect(path.clone()).wait().unwrap();
let client = Connection::<_, JsonCodec<Test, Test, JsonError>>::new(stream);
// Split RX and TX
let (tx, rx) = client.split();
// Send something (remember to .wait())
tx.send(Request::Something).wait().unwrap();
// Receive something (also remember to wait)
rx.map(|resp| -> Result<(), DaemonError> {
println!("Response: {:?}", resp);
Ok(())
}).wait().next();
Server
extern crate tokio;
use tokio::prelude::*;
use tokio::{run, spawn};
extern crate daemon_engine;
use daemon_engine::Server;
use daemon_engine::codecs::json::{JsonCodec, JsonError};
...
let server_handle = future::lazy(move || {
// Create server instance using the JSON codec, this must be executed from within a tokio context
let mut server = Server::<_, JsonCodec<Request, Response, JsonError>>::new_unix(&server_path).unwrap();
// Handle requests from clients
s.incoming().unwrap().for_each(move |r| {
println!("Request: {:?}", r.data());
let data = r.data();
match data {
...
_ => {
r.send(Response::Something(v.to_string()))
}
// Remember you have to .wait or otherwise prompt for send to occur
}.wait().unwrap();
Ok(())
}).map_err(|_e| ());
// do more stuff
...
// Close the server when you're done
s.close();
Ok(())
});
// Create server task
tokio::run(server_handle);
If you have any questions, comments, or suggestions, feel free to open an issue or a pull request.
Dependencies
~10MB
~170K SLoC