与Hyper同时获取多个URL

时间:2018-03-03 18:53:55

标签: rust hyper rust-tokio

我正在尝试调整Hyper basic client example以同时获取多个网址。

这是我目前的代码:

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use std::iter;
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;

fn get_url() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());
    let uris: Vec<_> = iter::repeat("http://httpbin.org/ip".parse().unwrap()).take(50).collect();
    for uri in uris {
        let work = client.get(uri).and_then(|res| {
            println!("Response: {}", res.status());

            res.body().for_each(|chunk| {
                io::stdout()
                    .write_all(&chunk)
                    .map_err(From::from)
            })
        });
        core.run(work).unwrap();
    }
}

fn main() {
    get_url();
}

它似乎并不是同时行动(需要很长时间才能完成),我是否以错误的方式将工作交给了核心?

1 个答案:

答案 0 :(得分:4)

  

我是以错误的方式将工作交给核心了吗?

是的,您正在向Tokio发出一个请求,并要求在开始下一个请求之前完成。您已采用异步代码并强制它成为顺序代码。

您需要为反应堆提供一个可以执行不同类型并发工作的未来:

use futures::{stream, Future, Stream}; // 0.1.25
use hyper::Client; // 0.12.23
use std::{
    io::{self, Write},
    iter,
};
use tokio; // 0.1.15

const N_PARALLEL: usize = 1;

fn main() {
    let client = Client::new();

    let uri = "http://httpbin.org/ip".parse().unwrap();
    let uris = iter::repeat(uri).take(50);

    let work = stream::iter_ok(uris)
        .map(move |uri| client.get(uri))
        .buffer_unordered(N_PARALLEL)
        .and_then(|res| {
            println!("Response: {}", res.status());
            res.into_body()
                .concat2()
                .map_err(|e| panic!("Error collecting body: {}", e))
        })
        .for_each(|body| {
            io::stdout()
                .write_all(&body)
                .map_err(|e| panic!("Error writing: {}", e))
        })
        .map_err(|e| panic!("Error making request: {}", e));

    tokio::run(work);
}

N_PARALLEL设置为1:

real    0m2.279s
user    0m0.193s
sys     0m0.065s

并设置为10:

real    0m0.529s
user    0m0.186s
sys     0m0.075s