diff --git a/client/src/types.rs b/client/src/types.rs deleted file mode 100644 index e69de29..0000000 diff --git a/server/Cargo.toml b/server/Cargo.toml index cb3f706..cde8220 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -4,3 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0" +futures = "0.3" +tarpc = { version = "0.34.0", features = ["full"] } +tokio = { version = "1.0", features = ["macros", "net", "rt-multi-thread"] } +tracing = "0.1.40" +clap = { version = "4.5.7", features = ["derive"] } \ No newline at end of file diff --git a/server/src/lib.rs b/server/src/lib.rs new file mode 100644 index 0000000..ce433f0 --- /dev/null +++ b/server/src/lib.rs @@ -0,0 +1,2 @@ +pub mod server; +pub mod types; \ No newline at end of file diff --git a/server/src/main.rs b/server/src/main.rs index e7a11a9..f09d6ef 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,3 +1,45 @@ -fn main() { - println!("Hello, world!"); +use std::future::Future; +use std::net::{IpAddr, Ipv6Addr}; +use futures::future::{self}; +use futures::StreamExt; +use tarpc::{ + server::{Channel}, + tokio_serde::formats::Json, +}; +use tarpc::server::incoming::Incoming; +use tarpc::server::BaseChannel; +use realm_server::server::RealmChatServer; +use realm_server::types::RealmChat; + +async fn spawn(fut: impl Future + Send + 'static) { + tokio::spawn(fut); } + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let server_addr = (IpAddr::V6(Ipv6Addr::LOCALHOST), 5051); + + // JSON transport is provided by the json_transport tarpc module. It makes it easy + // to start up a serde-powered json serialization strategy over TCP. + let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default).await?; + tracing::info!("Listening on port {}", listener.local_addr().port()); + listener.config_mut().max_frame_length(usize::MAX); + listener + // Ignore accept errors. + .filter_map(|r| future::ready(r.ok())) + .map(BaseChannel::with_defaults) + // Limit channels to 1 per IP. + .max_channels_per_key(1, |t| t.transport().peer_addr().unwrap().ip()) + // serve is generated by the service attribute. It takes as input any type implementing + // the generated World trait. + .map(|channel| { + let server = RealmChatServer(channel.transport().peer_addr().unwrap()); + channel.execute(server.serve()).for_each(spawn) + }) + // Max 10 channels. + .buffer_unordered(10) + .for_each(|_| async {}) + .await; + + Ok(()) +} \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs new file mode 100644 index 0000000..4e020bc --- /dev/null +++ b/server/src/server.rs @@ -0,0 +1,14 @@ +use std::net::SocketAddr; +use futures::future; +use futures::future::Ready; +use tarpc::context::Context; +use crate::types::RealmChat; + +#[derive(Clone)] +pub struct RealmChatServer(pub SocketAddr); + +impl RealmChat for RealmChatServer { + fn test(self, context: Context, name: String) -> Ready { + future::ready(format!("Hello, {name}!")) + } +} \ No newline at end of file diff --git a/server/src/types.rs b/server/src/types.rs new file mode 100644 index 0000000..17392c9 --- /dev/null +++ b/server/src/types.rs @@ -0,0 +1,4 @@ +#[tarpc::service] +pub trait RealmChat { + async fn test(name: String) -> String; +} \ No newline at end of file