Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Parameter passing issues in the tonic encapsulation middleware
---------------Original code---------------------
use axum::{extract::Request, http::StatusCode, middleware::Next, response::Response};
use tonic::transport::Server as TServer;
async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
Ok(next.run(req).await)
}
struct GrpcLogic {}
impl GrpcLogic {
fn new() -> Self {
Self {}
}
}
#[tonic::async_trait]
impl xxx for GrpcLogic {
// ...Implement the service specified in the proto file
}
#[tokio::main]
async fn main() {
let address = "[::1]:4000".to_string().parse().unwrap();
// AccountServer # tonic_build is the server-side code generated based on the proto file
let svc = AccountServer::new(GrpcLogic::new());
let layer = tower::ServiceBuilder::new()
.layer(axum::middleware::from_fn(auth))
.into_inner();
TServer::builder()
.layer(layer)
.add_service(svc)
.serve(address)
.await
.unwrap();
}
---------------Encapsulation code---------------------
use axum::{extract::Request, http::StatusCode, middleware::Next, response::Response};
use axum::{response::IntoResponse, routing::Route};
use std::convert::Infallible;
use tonic::transport::Server as TServer;
use tonic::{body::Body, server::NamedService};
use tower_layer::Layer;
use tower_service::Service;
async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
Ok(next.run(req).await)
}
struct GrpcLogic {}
impl GrpcLogic {
fn new() -> Self {
Self {}
}
}
#[tonic::async_trait]
impl xxx for GrpcLogic {
// ...Implement the service specified in the proto file
}
#[tokio::main]
async fn main() {
let layer = tower::ServiceBuilder::new()
.layer(axum::middleware::from_fn(auth))
.into_inner();
GrpcServer::new(AccountServer::new(GrpcLogic::new()))
.address("[::1]:4000")
.layer(layer)
.start()
.await
}
struct GrpcServer<L, S> {
address: String,
layer: Option<L>,
service: S,
}
impl<L, S> GrpcServer<L, S>
where
L: Layer<Route> + Clone + Send + Sync + 'static,
L::Service: Service<Request> + Clone + Send + Sync + 'static,
<L::Service as Service<Request>>::Response: IntoResponse + 'static,
<L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
<L::Service as Service<Request>>::Future: Send + 'static,
// ---
S: Service<Request<Body>, Error = Infallible> + NamedService + Clone + Send + Sync + 'static,
S::Response: axum::response::IntoResponse,
S::Future: Send + 'static,
{
fn new(srv: S) -> Self {
Self {
address: "[::1]:4000".to_string(),
layer: None,
service: srv,
}
}
fn address(mut self, a: &str) -> Self {
self.address = a.to_string();
self
}
fn layer(mut self, layer: L) -> Self {
self.layer = Some(layer);
self
}
async fn start(&self) -> Result<(), &str> {
let address = self.address.parse().unwrap();
let layer = self.layer.unwrap();
// let layer = tower::ServiceBuilder::new()
// .layer(axum::middleware::from_fn(auth))
// .into_inner();
TServer::builder()
.layer(layer)
.add_service(self.service.clone())
.serve(address)
.await
.unwrap();
Ok(())
}
}
Problem description: In the encapsulated code, under the start method
Use let layer = self.layer.unwrap();
An error will be reported. The error code is as follows:
error[E0277]: the trait bound `L: Layer<Routes>` is not satisfied
--> src\transport\grpc\mod.rs:57:14
|
57 | .serve(address)
| ^^^^^ the trait `Layer<Routes>` is not implemented for `L`
|
= note: required for `Stack<L, tower_layer::Identity>` to implement `Layer<Routes>`
Comment out let layer = self.layer.unwrap();
Use tower::ServiceBuilder
instead.
let layer = tower::ServiceBuilder::new()
.layer(DemoLayer::new())
.into_inner();
It's normal. This indicates that there is a problem with self.layer, but we still can't find a solution, so we come to seek help from everyone
1 post - 1 participant
🏷️ rust_feed