Skip to content

Commit f6439bc

Browse files
committed
multiple rpc in one file
1 parent fe134d4 commit f6439bc

7 files changed

Lines changed: 177 additions & 38 deletions

File tree

proto/misc.proto

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@ message HealthCheckResponse {
1010
bool status = 1;
1111
}
1212

13+
message SetupRequest {
14+
}
15+
16+
message SetupResponse {
17+
bool status = 1;
18+
}
19+
1320

14-
// Misc is a simple service that provides miscellaneous RPC methods.
21+
/// Misc is a simple service that provides miscellaneous RPC methods.
1522
service Misc {
16-
// HealthCheck is a simple RPC method that can be used to check the health of the service.
23+
/// HealthCheck is a simple RPC method that can be used to check the health of the service.
1724
rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);
25+
26+
/// Setup is a simple RPC method that can be used to setup the service.
27+
rpc Setup(SetupRequest) returns (SetupResponse);
1828
}

src/infra/app.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
use axum::Router;
1+
use crate::infra::setup::AppState;
2+
use crate::pages::app::App;
3+
use crate::pages::shell::Shell;
24
use axum::response::IntoResponse;
5+
use axum::Router;
36
use leptos::config::LeptosOptions;
47
use leptos::prelude::provide_context;
58
use leptos_axum::{generate_route_list, LeptosRoutes};
69
use tower::ServiceExt;
710
use tower_http::services::ServeDir;
8-
use crate::infra::setup::AppState;
9-
use crate::pages::app::App;
10-
use crate::pages::shell::Shell;
1111

1212
pub async fn create_app(state: AppState) -> crate::error::Result<Router> {
13-
1413
let leptos_options = state.leptos_options.clone();
1514
// let leptos_options = state.leptos_options;
1615
// Generate the list of routes in your Leptos App
@@ -21,12 +20,12 @@ pub async fn create_app(state: AppState) -> crate::error::Result<Router> {
2120
crate::infra::grpc::helloworld::greeter_server::GreeterServer::new(my_hello_server);
2221

2322
let my_misc_server = crate::infra::grpc::misc_server::MyMisc::default();
24-
let my_misc_service =
25-
crate::infra::grpc::misc::misc_server::MiscServer::new(my_misc_server);
23+
let my_misc_service = crate::infra::grpc::misc::misc_server::MiscServer::new(my_misc_server);
2624

2725
let router = Router::<AppState>::new()
2826
.route_service("/helloworld.Greeter/SayHello", my_hello_service)
29-
.route_service("/misc.Misc/HealthCheck", my_misc_service)
27+
.route_service("/misc.Misc/HealthCheck", my_misc_service.clone())
28+
.route_service("/misc.Misc/Setup", my_misc_service)
3029
.leptos_routes_with_context(
3130
&state,
3231
routes,
@@ -43,15 +42,11 @@ pub async fn create_app(state: AppState) -> crate::error::Result<Router> {
4342
ServeDir::new(std::path::Path::new(&*leptos_options.site_root).join("pkg")),
4443
)
4544
.nest_service("/public", ServeDir::new(std::path::Path::new("public")))
46-
47-
.fallback(file_and_error_handler)
48-
;
45+
.fallback(file_and_error_handler);
4946

5047
Ok(router.with_state(state))
51-
5248
}
5349

54-
5550
pub async fn file_and_error_handler(
5651
uri: axum::http::Uri,
5752
axum::extract::State(options): axum::extract::State<LeptosOptions>,
@@ -69,7 +64,6 @@ pub async fn file_and_error_handler(
6964
}
7065
}
7166

72-
7367
pub async fn get_static_file(
7468
uri: axum::http::Uri,
7569
root: &str,

src/infra/grpc/misc.rs

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ pub struct HealthCheckResponse {
66
#[prost(bool, tag = "1")]
77
pub status: bool,
88
}
9+
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
10+
pub struct SetupRequest {}
11+
#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
12+
pub struct SetupResponse {
13+
#[prost(bool, tag = "1")]
14+
pub status: bool,
15+
}
916
/// Generated client implementations.
1017
pub mod misc_client {
1118
#![allow(
@@ -17,7 +24,7 @@ pub mod misc_client {
1724
)]
1825
use tonic::codegen::*;
1926
use tonic::codegen::http::Uri;
20-
/// Misc is a simple service that provides miscellaneous RPC methods.
27+
/// / Misc is a simple service that provides miscellaneous RPC methods.
2128
#[derive(Debug, Clone)]
2229
pub struct MiscClient<T> {
2330
inner: tonic::client::Grpc<T>,
@@ -98,7 +105,7 @@ pub mod misc_client {
98105
self.inner = self.inner.max_encoding_message_size(limit);
99106
self
100107
}
101-
/// HealthCheck is a simple RPC method that can be used to check the health of the service.
108+
/// / HealthCheck is a simple RPC method that can be used to check the health of the service.
102109
pub async fn health_check(
103110
&mut self,
104111
request: impl tonic::IntoRequest<super::HealthCheckRequest>,
@@ -120,6 +127,25 @@ pub mod misc_client {
120127
req.extensions_mut().insert(GrpcMethod::new("misc.Misc", "HealthCheck"));
121128
self.inner.unary(req, path, codec).await
122129
}
130+
/// / Setup is a simple RPC method that can be used to setup the service.
131+
pub async fn setup(
132+
&mut self,
133+
request: impl tonic::IntoRequest<super::SetupRequest>,
134+
) -> std::result::Result<tonic::Response<super::SetupResponse>, tonic::Status> {
135+
self.inner
136+
.ready()
137+
.await
138+
.map_err(|e| {
139+
tonic::Status::unknown(
140+
format!("Service was not ready: {}", e.into()),
141+
)
142+
})?;
143+
let codec = tonic_prost::ProstCodec::default();
144+
let path = http::uri::PathAndQuery::from_static("/misc.Misc/Setup");
145+
let mut req = request.into_request();
146+
req.extensions_mut().insert(GrpcMethod::new("misc.Misc", "Setup"));
147+
self.inner.unary(req, path, codec).await
148+
}
123149
}
124150
}
125151
/// Generated server implementations.
@@ -135,16 +161,21 @@ pub mod misc_server {
135161
/// Generated trait containing gRPC methods that should be implemented for use with MiscServer.
136162
#[async_trait]
137163
pub trait Misc: std::marker::Send + std::marker::Sync + 'static {
138-
/// HealthCheck is a simple RPC method that can be used to check the health of the service.
164+
/// / HealthCheck is a simple RPC method that can be used to check the health of the service.
139165
async fn health_check(
140166
&self,
141167
request: tonic::Request<super::HealthCheckRequest>,
142168
) -> std::result::Result<
143169
tonic::Response<super::HealthCheckResponse>,
144170
tonic::Status,
145171
>;
172+
/// / Setup is a simple RPC method that can be used to setup the service.
173+
async fn setup(
174+
&self,
175+
request: tonic::Request<super::SetupRequest>,
176+
) -> std::result::Result<tonic::Response<super::SetupResponse>, tonic::Status>;
146177
}
147-
/// Misc is a simple service that provides miscellaneous RPC methods.
178+
/// / Misc is a simple service that provides miscellaneous RPC methods.
148179
#[derive(Debug)]
149180
pub struct MiscServer<T> {
150181
inner: Arc<T>,
@@ -264,6 +295,49 @@ pub mod misc_server {
264295
};
265296
Box::pin(fut)
266297
}
298+
"/misc.Misc/Setup" => {
299+
#[allow(non_camel_case_types)]
300+
struct SetupSvc<T: Misc>(pub Arc<T>);
301+
impl<T: Misc> tonic::server::UnaryService<super::SetupRequest>
302+
for SetupSvc<T> {
303+
type Response = super::SetupResponse;
304+
type Future = BoxFuture<
305+
tonic::Response<Self::Response>,
306+
tonic::Status,
307+
>;
308+
fn call(
309+
&mut self,
310+
request: tonic::Request<super::SetupRequest>,
311+
) -> Self::Future {
312+
let inner = Arc::clone(&self.0);
313+
let fut = async move {
314+
<T as Misc>::setup(&inner, request).await
315+
};
316+
Box::pin(fut)
317+
}
318+
}
319+
let accept_compression_encodings = self.accept_compression_encodings;
320+
let send_compression_encodings = self.send_compression_encodings;
321+
let max_decoding_message_size = self.max_decoding_message_size;
322+
let max_encoding_message_size = self.max_encoding_message_size;
323+
let inner = self.inner.clone();
324+
let fut = async move {
325+
let method = SetupSvc(inner);
326+
let codec = tonic_prost::ProstCodec::default();
327+
let mut grpc = tonic::server::Grpc::new(codec)
328+
.apply_compression_config(
329+
accept_compression_encodings,
330+
send_compression_encodings,
331+
)
332+
.apply_max_message_size_config(
333+
max_decoding_message_size,
334+
max_encoding_message_size,
335+
);
336+
let res = grpc.unary(method, req).await;
337+
Ok(res)
338+
};
339+
Box::pin(fut)
340+
}
267341
_ => {
268342
Box::pin(async move {
269343
let mut response = http::Response::new(

src/infra/grpc/misc_server.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(feature = "ssr")]
22
use tonic::{Request, Response, Status};
33

4-
use crate::infra::grpc::misc::{HealthCheckRequest, HealthCheckResponse, misc_server::Misc};
4+
use crate::infra::grpc::misc::{HealthCheckRequest, HealthCheckResponse, SetupRequest, SetupResponse, misc_server::Misc};
55

66

77

@@ -23,4 +23,17 @@ impl Misc for MyMisc {
2323

2424
Ok(Response::new(request))
2525
}
26+
27+
async fn setup (
28+
&self,
29+
request: Request<SetupRequest>,
30+
) -> Result<Response<SetupResponse>, Status> {
31+
println!("Got a setup request: {:?}", request);
32+
33+
let request = SetupResponse {
34+
status: true,
35+
};
36+
37+
Ok(Response::new(request))
38+
}
2639
}

src/main.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
1-
21
#[cfg(feature = "ssr")]
32
use new_avored::error::Result;
4-
3+
#[cfg(feature = "ssr")]
4+
use new_avored::infra::app::create_app;
5+
#[cfg(feature = "ssr")]
6+
use new_avored::infra::setup::init_app_state;
57

68
#[cfg(feature = "ssr")]
79
#[tokio::main]
8-
async fn main() -> Result<()>{
9-
use new_avored::infra::setup::init_app_state;
10-
use new_avored::infra::app::create_app;
11-
10+
async fn main() -> Result<()> {
1211
let state = init_app_state().await?;
13-
// let conf = get_configuration(None).unwrap();
14-
// let addr = &state.leptos_options.site_addr;
15-
1612
let app = create_app(state).await?;
1713

18-
// run our app with hyper
19-
println!("listening on http://{}", 3000);
14+
println!("listening on http://0.0.0.0:3000");
2015
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
2116
axum::serve(listener, app).await.unwrap();
2217

@@ -26,6 +21,4 @@ async fn main() -> Result<()>{
2621
#[cfg(not(feature = "ssr"))]
2722
pub fn main() {
2823
// no client-side main function
29-
// unless we want this to work with e.g., Trunk for pure client-side testing
30-
// see lib.rs for hydration function instead
3124
}

src/pages/home_page.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
11
use leptos::prelude::*;
22

33

4+
5+
6+
#[server]
7+
pub async fn setup_grpc() -> Result<bool, ServerFnError> {
8+
#[cfg(feature = "ssr")]
9+
{
10+
use crate::infra::grpc::misc::{SetupRequest, misc_client::MiscClient};
11+
12+
let mut client: MiscClient<tonic::transport::Channel> =
13+
MiscClient::connect("http://127.0.0.1:3000")
14+
.await
15+
.map_err(|e| ServerFnError::new(format!("Connection failed: {}", e)))?;
16+
17+
let request = tonic::Request::new(SetupRequest { });
18+
19+
let response = client
20+
.setup(request)
21+
.await
22+
.map_err(|e| ServerFnError::new(format!("gRPC call failed: {}", e)))?;
23+
24+
Ok(response.into_inner().status)
25+
}
26+
#[cfg(not(feature = "ssr"))]
27+
{
28+
let _ = name;
29+
Err(ServerFnError::new(
30+
"Server function body should not be called on client",
31+
))
32+
}
33+
}
34+
35+
436
#[server]
537
pub async fn health_check_grpc() -> Result<bool, ServerFnError> {
638
#[cfg(feature = "ssr")]
@@ -79,6 +111,9 @@ pub fn HomePage() -> impl IntoView {
79111
let misc_action = ServerAction::<HealthCheckGrpc>::new();
80112
let misc_result = misc_action.value();
81113

114+
let setup_action = ServerAction::<SetupGrpc>::new();
115+
let setup_result = setup_action.value();
116+
82117
view! {
83118
<h1>"Welcome to Leptos!"</h1>
84119
<button on:click=on_click>"Click Me: " {count}</button>
@@ -141,6 +176,30 @@ pub fn HomePage() -> impl IntoView {
141176
}}
142177
</p>
143178

179+
<div>
180+
"New Setup Request"
181+
<ActionForm action=setup_action>
182+
183+
<button type="submit">
184+
"Call gRPC Setup"
185+
</button>
186+
187+
</ActionForm>
188+
</div>
189+
<p>
190+
{move || match setup_result.get() {
191+
None => "".to_string(),
192+
Some(Ok(msg)) => {
193+
if msg {
194+
"Setup Passed".to_string()
195+
} else {
196+
"Setup Failed".to_string()
197+
}
198+
},
199+
Some(Err(err)) => format!("Error: {}", err),
200+
}}
201+
</p>
202+
144203

145204
}
146205
}

style/main.scss

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)