2017-07-25 379 views
1

如何使用異步Hyper(> = 0.11)爲HTTP請求設置超時?如何在Rust中爲hyper,tokio和futures指定超時時間?

下面是代碼沒有超時的例子:在回答我自己的工作代碼示例的問題,基於由seanmonstar提供給Hyper Guide/General Timeout鏈接

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

use futures::Future; 
use hyper::Client; 
use tokio_core::reactor::Core; 

fn main() { 
    let mut core = Core::new().unwrap(); 
    let client = Client::new(&core.handle()); 

    let uri = "http://stackoverflow.com".parse().unwrap(); 
    let work = client.get(uri).map(|res| { 
     res.status() 
    }); 

    match core.run(work) { 
     Ok(status) => println!("Status: {}", status), 
     Err(e) => println!("Error: {:?}", e) 
    } 
} 

回答

1

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

use futures::Future; 
use futures::future::Either; 
use hyper::Client; 
use tokio_core::reactor::Core; 
use std::time::Duration; 
use std::io; 

fn main() { 
    let mut core = Core::new().unwrap(); 
    let handle = core.handle(); 
    let client = Client::new(&handle); 

    let uri: hyper::Uri = "http://stackoverflow.com".parse().unwrap(); 
    let request = client.get(uri.clone()).map(|res| res.status()); 

    let timeout = tokio_core::reactor::Timeout::new(Duration::from_millis(170), &handle).unwrap(); 

    let work = request.select2(timeout).then(|res| match res { 
     Ok(Either::A((got, _timeout))) => Ok(got), 
     Ok(Either::B((_timeout_error, _get))) => { 
      Err(hyper::Error::Io(io::Error::new(
       io::ErrorKind::TimedOut, 
       "Client timed out while connecting", 
      ))) 
     } 
     Err(Either::A((get_error, _timeout))) => Err(get_error), 
     Err(Either::B((timeout_error, _get))) => Err(From::from(timeout_error)), 
    }); 

    match core.run(work) { 
     Ok(status) => println!("OK: {:?}", status), 
     Err(e) => println!("Error: {:?}", e) 
    } 
} 
相關問題