tk-http 0.3.9

A full-features asynchronous HTTP implementation for tokio-rs stack, including websockets.
Documentation
extern crate futures;
extern crate tk_http;
extern crate argparse;
extern crate env_logger;
extern crate tokio_core;
#[macro_use] extern crate log;

use std::env;
use std::time::Duration;
use std::net::ToSocketAddrs;

use futures::{Future, Stream};
use futures::future::{FutureResult, ok};
use futures::sync::mpsc::unbounded;
use tokio_core::net::TcpStream;
use tokio_core::reactor::{Timeout};
use tk_http::websocket::{Loop, Frame, Error, Dispatcher, Config};
use tk_http::websocket::client::{HandshakeProto, SimpleAuthorizer};
use tk_http::websocket::Packet::{Text};

struct Echo;


impl Dispatcher for Echo {
    type Future = FutureResult<(), Error>;
    fn frame(&mut self, frame: &Frame) -> FutureResult<(), Error> {
        println!("Frame arrived: {:?}", frame);
        ok(())
    }
}


pub fn main() {
    if env::var("RUST_LOG").is_err() {
        env::set_var("RUST_LOG", "warn");
    }
    env_logger::init().unwrap();

    let mut lp = tokio_core::reactor::Core::new().expect("loop created");
    let handle = lp.handle();
    let h2 = lp.handle();
    let addr = ("echo.websocket.org", 80).to_socket_addrs()
        .expect("resolve address").next().expect("at least one IP");
    let wcfg = Config::new().done();

    lp.run(futures::lazy(move || {
        TcpStream::connect(&addr, &handle)
        .map_err(|e| error!("Error {}", e))
        .and_then(|sock| {
            HandshakeProto::new(sock, SimpleAuthorizer::new(
                "echo.websocket.org", "/"))
            .map_err(|e| error!("Error {}", e))
        })
        .and_then(move |(out, inp, ())| {
            println!("Connected");
            let (tx, rx) = unbounded();

            println!("Preparing to send packet in 5 seconds");
            let tx2 = tx.clone();
            h2.spawn(
                Timeout::new(Duration::new(5, 0), &h2).unwrap()
                .map_err(|_| unreachable!())
                .and_then(move |_| {
                    println!("Sending 'hello'");
                    tx2.unbounded_send(Text("hello".to_string()))
                    .map_err(|_| ())
                })
                .then(|_| Ok(())));

            let rx = rx.map_err(|_| format!("stream closed"));
            Loop::client(out, inp, rx, Echo, &wcfg, &h2)
            .map_err(|e| println!("websocket closed: {}", e))
        })
        .then(|_| -> Result<(), &'static str> { Ok(()) })
    })).expect("request failed");
}