replace tokio bare with tarpc
This commit is contained in:
parent
6c5cb21fe8
commit
d490ff1024
@ -7,9 +7,11 @@ authors = ["ntr <ntr@smokestack.io>"]
|
|||||||
rand = "0.5.4"
|
rand = "0.5.4"
|
||||||
uuid = { version = "0.5", features = ["serde", "v4"] }
|
uuid = { version = "0.5", features = ["serde", "v4"] }
|
||||||
tokio = "0.1"
|
tokio = "0.1"
|
||||||
tokio-io = "0.1"
|
tokio-core = "0.1"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
serde_derive = "1"
|
serde_derive = "1"
|
||||||
serde_cbor = "0.9"
|
serde_cbor = "0.9"
|
||||||
|
tarpc = "0.12.0"
|
||||||
|
tarpc-plugins = "0.4.0"
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
# Cryps ("creeps") // Creeptography
|
# Cryps ("creeps") // Creeptography
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```
|
||||||
|
rustup default nightly-2018-06-09-x86_64-unknown-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
## Items
|
## Items
|
||||||
|
|
||||||
## Rolling
|
## Rolling
|
||||||
|
|||||||
44
src/main.rs
44
src/main.rs
@ -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;
|
||||||
extern crate serde_cbor;
|
extern crate serde_cbor;
|
||||||
#[macro_use]
|
#[macro_use] extern crate serde_derive;
|
||||||
extern crate serde_derive;
|
|
||||||
|
|
||||||
extern crate tokio;
|
|
||||||
extern crate bytes;
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
#[macro_use]
|
|
||||||
extern crate futures;
|
|
||||||
|
|
||||||
mod cryp;
|
mod cryp;
|
||||||
mod combat;
|
mod combat;
|
||||||
@ -16,29 +19,8 @@ mod battle;
|
|||||||
mod skill;
|
mod skill;
|
||||||
mod net;
|
mod net;
|
||||||
|
|
||||||
|
use net::server;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
server()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
|
||||||
// }
|
|
||||||
220
src/net.rs
220
src/net.rs
@ -1,189 +1,43 @@
|
|||||||
use bytes::{BytesMut, Bytes, BufMut};
|
use futures::Future;
|
||||||
use futures::future::{self, Either};
|
use tarpc::future::{client, server};
|
||||||
use futures::sync::mpsc;
|
use tarpc::future::client::ClientExt;
|
||||||
use tokio::io;
|
use tarpc::util::{FirstSocketAddr, Never};
|
||||||
use tokio::net::TcpStream;
|
use tokio_core::reactor;
|
||||||
use tokio::prelude::*;
|
|
||||||
|
|
||||||
use cryp::{Cryp};
|
service! {
|
||||||
use skill::{Skill};
|
rpc hello(name: String) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
// struct Line {
|
#[derive(Clone)]
|
||||||
// socket: TcpStream,
|
struct HelloServer;
|
||||||
// rd: BytesMut,
|
|
||||||
// wr: BytesMut,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Line {
|
impl FutureService for HelloServer {
|
||||||
// /// Create a new `lines` codec backed by the socket
|
type HelloFut = Result<String, Never>;
|
||||||
// fn new(socket: TcpStream) -> Line {
|
|
||||||
// Line {
|
|
||||||
// socket,
|
|
||||||
// rd: BytesMut::new(),
|
|
||||||
// wr: BytesMut::new(),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Buffer a Line.
|
fn hello(&self, name: String) -> Self::HelloFut {
|
||||||
// ///
|
Ok(format!("Hello, {}!", name))
|
||||||
// /// 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());
|
|
||||||
|
|
||||||
// // Push the line onto the end of the write buffer.
|
pub fn server() {
|
||||||
// //
|
let mut reactor = reactor::Core::new().unwrap();
|
||||||
// // The `put` function is from the `BufMut` trait.
|
let (mut handle, server) = HelloServer
|
||||||
// self.wr.put(line);
|
.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
|
// let options = client::Options::default().handle(reactor.handle());
|
||||||
// fn poll_flush(&mut self) -> Poll<(), io::Error> {
|
// reactor
|
||||||
// // As long as there is buffered data to write, try to write it.
|
// .run(
|
||||||
// while !self.wr.is_empty() {
|
// FutureClient::connect(handle.addr(), options)
|
||||||
// // Try to write some bytes to the socket
|
// .map_err(|e| panic!("{:?}", e))
|
||||||
// let n = try_ready!(self.socket.poll_write(&self.wr));
|
// .and_then(|client| client.hello("Mom".to_string()))
|
||||||
|
// .map(|resp| println!("{}", resp)),
|
||||||
// // As long as the wr is not empty, a successful write should
|
// )
|
||||||
// // never write 0 bytes.
|
// .unwrap();
|
||||||
// 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);
|
|
||||||
// }
|
|
||||||
Loading…
x
Reference in New Issue
Block a user