// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the MIT License, . // This file may not be copied, modified, or distributed except according to those terms. #![feature(conservative_impl_trait, plugin)] #![plugin(tarpc_plugins)] extern crate bincode; extern crate env_logger; extern crate futures; #[macro_use] extern crate log; #[macro_use] extern crate serde_derive; #[macro_use] extern crate tarpc; extern crate tokio_core; extern crate tokio_service; use bincode::serde::DeserializeError; use futures::{Future, IntoFuture}; use std::io; use std::net::SocketAddr; use tarpc::client::future::{Connect, Options}; use tarpc::util::FirstSocketAddr; use tarpc::util::Never; use tokio_service::Service; #[derive(Clone, Copy)] struct HelloServer; impl HelloServer { fn listen(addr: SocketAddr) -> impl Future { let (tx, rx) = futures::oneshot(); tarpc::REMOTE.spawn(move |handle| { Ok(tx.complete(tarpc::listen_with(addr, move || Ok(HelloServer), handle.clone()))) }); rx.map_err(|e| panic!(e)).and_then(|result| result) } } impl Service for HelloServer { type Request = Result; type Response = tarpc::Response; type Error = io::Error; type Future = Box, Error = io::Error>>; fn call(&self, request: Self::Request) -> Self::Future { Ok(Ok(format!("Hello, {}!", request.unwrap()))).into_future().boxed() } } /// The client stub that makes RPC calls to the server. Exposes a Future interface. #[derive(Debug)] pub struct FutureClient(tarpc::Client); impl FutureClient { fn connect(addr: SocketAddr) -> impl Future { tarpc::Client::connect(addr, Options::default()).map(FutureClient) } pub fn hello(&self, name: String) -> impl Future> + 'static { self.0.call(name).then(|msg| msg.unwrap()) } } fn main() { let _ = env_logger::init(); let mut core = tokio_core::reactor::Core::new().unwrap(); let addr = HelloServer::listen("localhost:10000".first_socket_addr()).wait().unwrap(); let f = FutureClient::connect(addr) .map_err(tarpc::Error::from) .and_then(|client| { let resp1 = client.hello("Mom".to_string()); info!("Sent first request."); let resp2 = client.hello("Dad".to_string()); info!("Sent second request."); futures::collect(vec![resp1, resp2]) }) .map(|responses| { for resp in responses { println!("{}", resp); } }); core.run(f).unwrap(); }