Prost is a crate implementing protobuf encode/decoding.
cargo add prost
cargo add prost-types // if you need to use common protobuf types such as Struct, Timestamp, ...
let now = chrono::offset::Utc::now();
let timestamp = prost_types::Timestamp {
seconds: now.timestamp(),
nanos: now.timestamp_subsec_nanos() as i32,
};
TBD
Tonic is a crate implementing the gRPC protocol on top of HTTP/2 and Prost.
File hierarchy used for this section.
proto/
metrics/
v1/
metrics_service.proto
...
src/
lib.rs
Cargo.toml
build.rs
Add the following dependencies in Cargo.toml.
[dependencies]
tonic = "0.5"
prost = "0.8"
[build-dependencies]
tonic-build = "0.5"
Add the following build.rs
file at the root level.
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure().compile(
&[
"proto/metrics/v1/metrics_service.proto",
...
],
&["proto"],
)?;
Ok(())
}
Declare the modules generated by Tonic in lib.rs
pub mod metrics {
pub mod proto {
pub mod v1 {
tonic::include_proto!("metrics.v1");
}
}
...
}
Based on SO_REUSEPORT.
let service = YourGrpcService::default();
let addr: std::net::SocketAddr = "0.0.0.0:<port>".parse().unwrap();
let sock = socket2::Socket::new(
match addr {
SocketAddr::V4(_) => socket2::Domain::IPV4,
SocketAddr::V6(_) => socket2::Domain::IPV6,
},
socket2::Type::STREAM,
None,
).unwrap();
sock.set_reuse_address(true).unwrap();
sock.set_reuse_port(true).unwrap();
sock.set_nonblocking(true).unwrap();
sock.bind(&addr.into()).unwrap();
sock.listen(8192).unwrap();
let incoming = tokio_stream::wrappers::TcpListenerStream::new(TcpListener::from_std(sock.into()).unwrap());
Server::builder()
.add_service(YourGrpcService::new(service))
.serve_with_incoming(incoming)
.await
.unwrap();