gRPC
Basic implementation that currently only supports unary calls. gRPC is an high-performance remote procedure call framework developed by Google that enables efficient communication between distributed systems, particularly in microservices architectures.
wtx does not provide built-in deserialization or serialization utilities capable of manipulate protobuf files. Instead, users are free to choose any third-party that generates Rust bindings and implements the internal Deserialize and Serialize traits.
Due to the lack of an official parser, the definitions of a Service must be manually typed.
Independent benchmarks are available at https://github.com/LesnyRumcajs/grpc_bench.
Client Example
To use this functionality, it is necessary to activate the grpc-client feature.
//! gRPC client that uses the structure definitions found in the `wtx_instances::grpc_bindings`
//! module.
extern crate tokio;
extern crate wtx;
extern crate wtx_instances;
use std::borrow::Cow;
use wtx::{
de::format::QuickProtobuf,
grpc::GrpcClient,
http::{ReqResBuffer, client_pool::ClientPoolBuilder},
};
use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse};
#[tokio::main]
async fn main() -> wtx::Result<()> {
let rrb = ReqResBuffer::empty();
let uri_ref = rrb.uri.to_ref();
let pool = ClientPoolBuilder::tokio(1).build();
let mut guard = pool.lock(&uri_ref).await?;
let mut client = GrpcClient::new(&mut guard.client, QuickProtobuf);
let res = client
.send_unary_req(
GenericRequest {
generic_request_field0: Cow::Borrowed(b"generic_request_value"),
generic_request_field1: 123,
},
rrb,
&"http://127.0.0.1:9000/wtx.GenericService/generic_method".into(),
)
.await?;
let generic_response: GenericResponse = client.des_from_res_bytes(&mut res.rrd.body.as_ref())?;
println!("{generic_response:?}");
Ok(())
}
Server Example
To use this functionality, it is necessary to activate the grpc-server feature.
//! gRPC server that uses the structure definitions found in the `wtx_instances::grpc_bindings`
//! module.
extern crate tokio;
extern crate wtx;
extern crate wtx_instances;
use std::borrow::Cow;
use wtx::{
de::format::QuickProtobuf,
grpc::{GrpcManager, GrpcMiddleware},
http::{
ReqResBuffer, StatusCode,
server_framework::{Router, ServerFrameworkBuilder, State, post},
},
rng::{Xorshift64, simple_seed},
};
use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse};
#[tokio::main]
async fn main() -> wtx::Result<()> {
let router = Router::new(
wtx::paths!(("wtx.GenericService/generic_method", post(wtx_generic_service_generic_method))),
GrpcMiddleware,
)?;
ServerFrameworkBuilder::new(Xorshift64::from(simple_seed()), router)
.with_stream_aux(|_| Ok(QuickProtobuf))
.tokio_rustls(
(wtx_instances::CERT, wtx_instances::KEY),
&wtx_instances::host_from_args(),
|error| eprintln!("{error}"),
|_| Ok(()),
|error| eprintln!("{error}"),
)
.await
}
async fn wtx_generic_service_generic_method(
state: State<'_, (), GrpcManager<QuickProtobuf>, ReqResBuffer>,
) -> wtx::Result<StatusCode> {
let _generic_request: GenericRequest =
state.stream_aux.des_from_req_bytes(&mut state.req.rrd.body.as_ref())?;
state.req.clear();
state.stream_aux.ser_to_res_bytes(
&mut state.req.rrd.body,
GenericResponse {
generic_response_field0: Cow::Borrowed(b"generic_response_value"),
generic_response_field1: 321,
},
)?;
Ok(StatusCode::Ok)
}