mirror of
https://github.com/OMGeeky/tarpc.git
synced 2026-01-02 17:42:23 +01:00
82 lines
3.0 KiB
Rust
82 lines
3.0 KiB
Rust
// Copyright 2018 Google LLC
|
|
//
|
|
// Use of this source code is governed by an MIT-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://opensource.org/licenses/MIT.
|
|
|
|
#![feature(async_await)]
|
|
|
|
use futures::{
|
|
future::{self, Ready},
|
|
prelude::*,
|
|
};
|
|
use rpc::{
|
|
client, context,
|
|
server::{BaseChannel, Channel},
|
|
};
|
|
use std::io;
|
|
|
|
// This is the service definition. It looks a lot like a trait definition.
|
|
// It defines one RPC, hello, which takes one arg, name, and returns a String.
|
|
|
|
#[tarpc::service]
|
|
pub trait Service {
|
|
async fn hello(name: String) -> String;
|
|
}
|
|
|
|
// This is the type that implements the generated Service trait. It is the business logic
|
|
// and is used to start the server.
|
|
#[derive(Clone)]
|
|
struct HelloServer;
|
|
|
|
impl Service for HelloServer {
|
|
// Each defined rpc generates two items in the trait, a fn that serves the RPC, and
|
|
// an associated type representing the future output by the fn.
|
|
|
|
type HelloFut = Ready<String>;
|
|
|
|
fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
|
|
future::ready(format!("Hello, {}!", name))
|
|
}
|
|
}
|
|
|
|
#[runtime::main(runtime_tokio::Tokio)]
|
|
async fn main() -> io::Result<()> {
|
|
// bincode_transport is provided by the associated crate bincode-transport. It makes it easy
|
|
// to start up a serde-powered bincode serialization strategy over TCP.
|
|
let mut transport = bincode_transport::listen(&"0.0.0.0:0".parse().unwrap())?;
|
|
let addr = transport.local_addr();
|
|
|
|
let server = async move {
|
|
// For this example, we're just going to wait for one connection.
|
|
let client = transport.next().await.unwrap().unwrap();
|
|
|
|
// `Channel` is a trait representing a server-side connection. It is a trait to allow
|
|
// for some channels to be instrumented: for example, to track the number of open connections.
|
|
// BaseChannel is the most basic channel, simply wrapping a transport with no added
|
|
// functionality.
|
|
BaseChannel::with_defaults(client)
|
|
// serve is generated by the tarpc::service! macro. It takes as input any type implementing
|
|
// the generated Service trait.
|
|
.respond_with(serve(HelloServer))
|
|
.await;
|
|
};
|
|
let _ = runtime::spawn(server);
|
|
|
|
let transport = bincode_transport::connect(&addr).await?;
|
|
|
|
// new_stub is generated by the tarpc::service! macro. Like Server, it takes a config and any
|
|
// Transport as input, and returns a Client, also generated by the macro.
|
|
// by the service mcro.
|
|
let mut client = new_stub(client::Config::default(), transport).await?;
|
|
|
|
// The client has an RPC method for each RPC defined in tarpc::service!. It takes the same args
|
|
// as defined, with the addition of a Context, which is always the first arg. The Context
|
|
// specifies a deadline and trace information which can be helpful in debugging requests.
|
|
let hello = client.hello(context::current(), "Stim".to_string()).await?;
|
|
|
|
eprintln!("{}", hello);
|
|
|
|
Ok(())
|
|
}
|