【问题标题】:How can I return an Arc<Vec<u8>> as a Hyper response?如何将 Arc<Vec<u8>> 作为 Hyper 响应返回?
【发布时间】:2021-02-10 13:03:45
【问题描述】:

我正在编写一个在启动时分配一些压缩数据的服务器。现在,当我提供超响应时,我不想复制这些字节,但我想不出用超响应的方法。

我已经尝试为我自己的类型实现 HttpBody,但是对 trait 的生命周期限制阻止了我这样做。

我错过了什么吗?这是我正在尝试做的一个最小示例:

use hyper::{service::Service, Body, Request, Response, Server};
use std::net::SocketAddr;
use std::sync::Arc;

use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};

fn main() {
    let addr = SocketAddr::new("0.0.0.0".parse().unwrap(), 8080);
    println!("Server startup...");
    let rt = tokio::runtime::Runtime::new().unwrap();
    rt.block_on(async {
        let app = MakeSvc::new().await;
        let ret = app.clone();
        let server = Server::bind(&addr).serve(app);

        println!("Running on {}", &addr);
        server.await.unwrap();
    })
}

#[derive(Debug, Clone)]
pub struct WrapperApp {
    pub cache: Arc<Vec<u8>>,
}

impl WrapperApp {
    //Let's say I allocate some bytes here.
    async fn new() -> Self {
        Self {
            cache: Arc::new(Vec::new()),
        }
    }
}

impl Service<Request<Body>> for WrapperApp {
    type Response = Response<Body>;
    type Error = hyper::Error;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

    fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(()))
    }

    fn call(&mut self, req: Request<Body>) -> Self::Future {
        let a = Arc::clone(&self.cache);
        return Box::pin(async { Ok(Response::builder().body(Body::from(a)).unwrap()) });
    }
}

#[derive(Debug, Clone)]
pub struct MakeSvc {
    app: WrapperApp,
}

impl MakeSvc {
    pub async fn new() -> Self {
        Self {
            app: WrapperApp::new().await,
        }
    }
}

impl<T> Service<T> for MakeSvc {
    type Response = WrapperApp;
    type Error = hyper::Error;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

    fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
        Poll::Ready(Ok(()))
    }

    fn call(&mut self, _: T) -> Self::Future {
        let app = self.app.clone();
        let fut = async move { Ok(app) };
        Box::pin(fut)
    }
}
error[E0277]: the trait bound `Body: From<Arc<Vec<u8>>>` is not satisfied
  --> src/main.rs:50:61
   |
50 |         return Box::pin(async { Ok(Response::builder().body(Body::from(a)).unwrap()) });
   |                                                             ^^^^^^^^^^ the trait `From<Arc<Vec<u8>>>` is not implemented for `Body`
   |
   = help: the following implementations were found:
             <Body as From<&'static [u8]>>
             <Body as From<&'static str>>
             <Body as From<Box<(dyn futures_core::stream::Stream<Item = std::result::Result<hyper::body::Bytes, Box<(dyn std::error::Error + Send + Sync + 'static)>>> + Send + 'static)>>>
             <Body as From<Cow<'static, [u8]>>>
           and 4 others
   = note: required by `from`

与此相关的 Cargo.toml。该示例在我尝试使用参考的地方中断:

[package]
name = "hyper-ptr"
version = "0.1.0"
authors = ["Pierre Laas <lanklaas123@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
hyper={version="0.14", features=["server","http1","tcp"]}
tokio={version="1.0.0", features=["macros","io-util","rt-multi-thread"]}
serde={version="*", features=["derive","rc"]}
serde_json="*"
flate2="*"
openssl="*"
rand="*"

【问题讨论】:

    标签: rust ownership hyper


    【解决方案1】:

    documentation 开始,没有From 实现不需要'static 引用或主体所有权。

    相反,您可以克隆缓存。 Body::From 的实现需要 Vec&lt;u8&gt; 或静态数据的所有权(如果这对您的情况有用)。

    请注意,您需要先取消引用它:

    use hyper::Body; // 0.14.2
    use std::sync::Arc;
    
    const FOO: [u8; 1] = [8u8]; 
    
    fn main() {
        let cache = Arc::new(vec![0u8]);
        let body = Body::from((*cache).clone());
        let other_body = Body::from(&FOO[..]);
        println!("{:?}", cache);
    }
    

    Playground

    【讨论】:

    • 我试图取消弧线,但不是那样。谢谢
    猜你喜欢
    • 2020-10-28
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    相关资源
    最近更新 更多