replace tokio bare with tarpc

This commit is contained in:
ntr 2018-09-02 12:17:28 +10:00
parent 6c5cb21fe8
commit d490ff1024
4 changed files with 59 additions and 215 deletions

View File

@ -7,9 +7,11 @@ authors = ["ntr <ntr@smokestack.io>"]
rand = "0.5.4"
uuid = { version = "0.5", features = ["serde", "v4"] }
tokio = "0.1"
tokio-io = "0.1"
tokio-core = "0.1"
futures = "0.1"
bytes = "0.4"
serde = "1"
serde_derive = "1"
serde_cbor = "0.9"
tarpc = "0.12.0"
tarpc-plugins = "0.4.0"

View File

@ -1,5 +1,11 @@
# Cryps ("creeps") // Creeptography
## Setup
```
rustup default nightly-2018-06-09-x86_64-unknown-linux-gnu
```
## Items
## Rolling

View File

@ -1,14 +1,17 @@
// needed by tarpc until it becomes stable
#![feature(plugin, use_extern_macros, proc_macro_path_invoc)]
#![plugin(tarpc_plugins)]
extern crate tokio_core;
#[macro_use] extern crate futures;
#[macro_use] extern crate tarpc;
extern crate serde;
extern crate serde_cbor;
#[macro_use]
extern crate serde_derive;
#[macro_use] extern crate serde_derive;
extern crate tokio;
extern crate bytes;
extern crate rand;
extern crate uuid;
#[macro_use]
extern crate futures;
mod cryp;
mod combat;
@ -16,29 +19,8 @@ mod battle;
mod skill;
mod net;
use net::server;
fn main() {
}
// use tokio::net::TcpListener;
// use tokio::prelude::*;
// use std::net::SocketAddr;
// use net::{process};
// fn main() {
// let addr = "0.0.0.0:40000".to_string();
// let addr = addr.parse::<SocketAddr>().unwrap();
// let listener = TcpListener::bind(&addr).unwrap();
// println!("Listening on: {}", addr);
// let done = listener.incoming()
// .map_err(|e| println!("failed to accept socket; error = {:?}", e))
// .for_each(|socket| {
// process(socket)
// });
// tokio::run(done);
// }
server()
}

View File

@ -1,189 +1,43 @@
use bytes::{BytesMut, Bytes, BufMut};
use futures::future::{self, Either};
use futures::sync::mpsc;
use tokio::io;
use tokio::net::TcpStream;
use tokio::prelude::*;
use futures::Future;
use tarpc::future::{client, server};
use tarpc::future::client::ClientExt;
use tarpc::util::{FirstSocketAddr, Never};
use tokio_core::reactor;
use cryp::{Cryp};
use skill::{Skill};
service! {
rpc hello(name: String) -> String;
}
// struct Line {
// socket: TcpStream,
// rd: BytesMut,
// wr: BytesMut,
// }
#[derive(Clone)]
struct HelloServer;
// impl Line {
// /// Create a new `lines` codec backed by the socket
// fn new(socket: TcpStream) -> Line {
// Line {
// socket,
// rd: BytesMut::new(),
// wr: BytesMut::new(),
// }
// }
impl FutureService for HelloServer {
type HelloFut = Result<String, Never>;
// /// Buffer a Line.
// ///
// /// This writes the Line to an internal buffer. Calls to `poll_flush` will
// /// attempt to flush this buffer to the socket.
// fn buffer(&mut self, line: &[u8]) {
// // Ensure the buffer has capacity. Ideally this would not be unbounded,
// // but to keep the example simple, we will not limit this.
// self.wr.reserve(line.len());
fn hello(&self, name: String) -> Self::HelloFut {
Ok(format!("Hello, {}!", name))
}
}
// // Push the line onto the end of the write buffer.
// //
// // The `put` function is from the `BufMut` trait.
// self.wr.put(line);
// }
pub fn server() {
let mut reactor = reactor::Core::new().unwrap();
let (mut handle, server) = HelloServer
.listen(
"localhost:10000".first_socket_addr(),
&reactor.handle(),
server::Options::default(),
)
.unwrap();
handle.wait();
reactor.handle().spawn(server);
// /// Flush the write buffer to the socket
// fn poll_flush(&mut self) -> Poll<(), io::Error> {
// // As long as there is buffered data to write, try to write it.
// while !self.wr.is_empty() {
// // Try to write some bytes to the socket
// let n = try_ready!(self.socket.poll_write(&self.wr));
// // As long as the wr is not empty, a successful write should
// // never write 0 bytes.
// assert!(n > 0);
// // This discards the first `n` bytes of the buffer.
// let _ = self.wr.split_to(n);
// }
// // Buffer is empty, everything written
// Ok(Async::Ready(()))
// }
// /// Read data from the socket.
// ///
// /// This only returns `Ready` when the socket has closed.
// fn fill_read_buf(&mut self) -> Poll<(), io::Error> {
// loop {
// // Ensure the read buffer has capacity.
// // This might result in an internal allocation.
// self.rd.reserve(1024);
// // Read data into the buffer.
// let n = try_ready!(self.socket.read_buf(&mut self.rd));
// if n == 0 {
// return Ok(Async::Ready(()));
// }
// }
// }
// }
// impl Stream for Line {
// type Item = BytesMut;
// type Error = io::Error;
// fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
// // First, read any new data that might have been received off the socket
// let sock_closed = self.fill_read_buf()?.is_ready();
// // Now, try finding line endings
// let pos = self.rd.windows(2).enumerate()
// .find(|&(_, bytes)| bytes == b"\r\n")
// .map(|(i, _)| i);
// if let Some(pos) = pos {
// // Remove the line from the read buffer and set it to `line`.
// let mut line = self.rd.split_to(pos + 2);
// // Drop the trailing \r\n
// line.split_off(pos);
// // Return the line
// return Ok(Async::Ready(Some(line)));
// }
// if sock_closed {
// Ok(Async::Ready(None))
// } else {
// Ok(Async::NotReady)
// }
// }
// }
// fn generate() -> Cryp {
// let a = Cryp::new()
// .named("pronounced \"creeep\"".to_string())
// .level(8)
// .learn(Skill::Stoney)
// .create();
// a
// }
// pub fn process(socket: TcpStream) {
// // Wrap the socket with the `lines` codec that we wrote above.
// //
// // By doing this, we can operate at the Line level instead of doing raw byte
// // manipulation.
// let lines = lines::new(socket);
// // The first Line is treated as the client's name. The client is not added
// // to the set of connected peers until this Line is received.
// //
// // We use the `into_future` combinator to extract the first item from the
// // lines stream. `into_future` takes a `Stream` and converts it to a future
// // of `(first, rest)` where `rest` is the original stream instance.
// let connection = lines.into_future()
// // `into_future` doesn't have the right error type, so map the error to
// // make it work.
// .map_err(|(e, _)| e)
// // Process the first received Line as the client's name.
// .and_then(|(name, lines)| {
// // If `name` is `None`, then the client disconnected without
// // actually sending a Line of data.
// //
// // Since the connection is closed, there is no further work that we
// // need to do. So, we just terminate processing by returning
// // `future::ok()`.
// //
// // The problem is that only a single future type can be returned
// // from a combinator closure, but we want to return both
// // `future::ok()` and `Peer` (below).
// //
// // This is a common problem, so the `futures` crate solves this by
// // providing the `Either` helper enum that allows creating a single
// // return type that covers two concrete future types.
// let name = match name {
// Some(name) => name,
// None => {
// // The remote client closed the connection without sending
// // any data.
// return Either::A(future::ok(()));
// }
// };
// println!("`{:?}` is joining the chat", name);
// // Create the peer.
// //
// // This is also a future that processes the connection, only
// // completing when the socket closes.
// let peer = Peer::new(
// name,
// state,
// lines);
// // Wrap `peer` with `Either::B` to make the return type fit.
// Either::B(peer)
// })
// // Task futures have an error of type `()`, this ensures we handle the
// // error. We do this by printing the error to STDOUT.
// .map_err(|e| {
// println!("connection error = {:?}", e);
// });
// // Spawn the task. Internally, this submits the task to a thread pool.
// tokio::spawn(connection);
// }
// let options = client::Options::default().handle(reactor.handle());
// reactor
// .run(
// FutureClient::connect(handle.addr(), options)
// .map_err(|e| panic!("{:?}", e))
// .and_then(|client| client.hello("Mom".to_string()))
// .map(|resp| println!("{}", resp)),
// )
// .unwrap();
}