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_examples;
use std::borrow::Cow;
use wtx::{
codec::format::QuickProtobuf,
executor::TokioExecutor,
grpc::GrpcClient,
http::{MsgBufferStr, http2_client_pool::Http2ClientPoolBuilder},
rng::{ChaCha20, CryptoSeedableRng as _},
tls::{TlsConfig, TlsModeVerified},
};
use wtx_examples::{
ROOT_CA,
grpc_bindings::wtx::{GenericRequest, GenericResponse},
};
#[tokio::main]
async fn main() -> wtx::Result<()> {
let uri = "https://127.0.0.1:9000/wtx.GenericService/generic_method";
let mut client = GrpcClient::new(
Http2ClientPoolBuilder::new(
TokioExecutor::default(),
1,
ChaCha20::from_getrandom()?,
TlsConfig::from_trust_anchors_pem(TlsModeVerified::default(), [ROOT_CA])?,
)?
.build(),
QuickProtobuf,
);
let res = client
.send_unary_req(
GenericRequest {
generic_request_field0: Cow::Borrowed(b"generic_request_value"),
generic_request_field1: 123,
},
MsgBufferStr::from_uri(uri.into()),
)
.await?;
let generic_response: GenericResponse = client.des_from_res_bytes(&res.msg_data.body)?;
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_examples;
use std::borrow::Cow;
use wtx::{
codec::format::QuickProtobuf,
grpc::{GrpcManager, GrpcMiddleware},
http::{
StatusCode,
http2_server_framework::{Http2ServerFramework, HttpRouter, State, post},
},
tls::{TlsConfig, TlsModeVerified},
};
use wtx_examples::{
PUBLIC_KEY, SECRET_KEY,
grpc_bindings::wtx::{GenericRequest, GenericResponse},
host_from_args,
};
fn main() -> wtx::Result<()> {
let router = HttpRouter::new(
wtx::paths!(("wtx.GenericService/generic_method", post(wtx_generic_service_generic_method))),
GrpcMiddleware,
)?;
Http2ServerFramework::tokio(TlsConfig::from_keys_pem(
TlsModeVerified::default(),
PUBLIC_KEY.try_into()?,
SECRET_KEY.try_into()?,
)?)?
.set_data(GrpcManager::from_drsr(QuickProtobuf))
.run_in_threads(&host_from_args(), router)
}
async fn wtx_generic_service_generic_method(
state: State<'_, GrpcManager<QuickProtobuf>>,
) -> wtx::Result<StatusCode> {
let _generic_request: GenericRequest = state.data.des_from_req_bytes(&state.req.msg_data.body)?;
state.req.clear();
state.data.ser_to_res_bytes(
&mut state.req.msg_data.body,
GenericResponse {
generic_response_field0: Cow::Borrowed(b"generic_response_value"),
generic_response_field1: 321,
},
)?;
Ok(StatusCode::Ok)
}