#16 Enable RPC to listen http:127.0.0.1 for for Windows and iOS sim
This commit is contained in:
parent
312b91fedb
commit
069ce417df
10 changed files with 62 additions and 37 deletions
|
|
@ -50,6 +50,7 @@ serde = { version = "1.0.219", features = ["derive"] }
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
|
tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
|
||||||
tonic = "0.14.0"
|
tonic = "0.14.0"
|
||||||
|
url = { version = "2.5.7", features = ["serde"] }
|
||||||
uuid = { version = "1.17.0", features = ["v7"] }
|
uuid = { version = "1.17.0", features = ["v7"] }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ pub struct PeerAddress(String);
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn add_cached_peers(mut commands: Commands) {
|
async fn add_cached_peers(mut commands: Commands) {
|
||||||
let config = CONFIG.get_unchecked();
|
let config = CONFIG.get_unchecked();
|
||||||
let path = String::from("unix://") + config.rpc.socket_path.as_os_str().to_str().expect("Invalid string");
|
let url = config.rpc.endpoint_url.to_string();
|
||||||
let mut client = caretta_sync_core::proto::cached_peer_service_client::CachedPeerServiceClient::connect(path).await.expect("Unix socket should be accessible");
|
let mut client = caretta_sync_core::proto::cached_peer_service_client::CachedPeerServiceClient::connect(url).await.expect("Unix socket should be accessible");
|
||||||
let request = tonic::Request::new(CachedPeerListRequest {});
|
let request = tonic::Request::new(CachedPeerListRequest {});
|
||||||
let response = client.list(request).await.expect("Faild to request/response");
|
let response = client.list(request).await.expect("Faild to request/response");
|
||||||
let peers = response.into_inner().peers;
|
let peers = response.into_inner().peers;
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ impl Runnable for PeerListCommandArgs {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn run(self, app_name: &'static str) {
|
async fn run(self, app_name: &'static str) {
|
||||||
let config = self.config.into_config(app_name).await;
|
let config = self.config.into_config(app_name).await;
|
||||||
let path = String::from("unix://") + config.rpc.socket_path.as_os_str().to_str().expect("Invalid string");
|
let url = config.rpc.endpoint_url.to_string();
|
||||||
let mut client = caretta_sync_core::proto::cached_peer_service_client::CachedPeerServiceClient::connect(path).await.expect("Unix socket should be accessible");
|
let mut client = caretta_sync_core::proto::cached_peer_service_client::CachedPeerServiceClient::connect(url).await.expect("Target endpoint should be accessible");
|
||||||
let request = tonic::Request::new(CachedPeerListRequest {});
|
let request = tonic::Request::new(CachedPeerListRequest {});
|
||||||
let response = client.list(request).await.expect("Faild to request/response");
|
let response = client.list(request).await.expect("Faild to request/response");
|
||||||
println!("{:?}", response);
|
println!("{:?}", response);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ libp2p.workspace = true
|
||||||
libp2p-core = { version = "0.43.0", features = ["serde"] }
|
libp2p-core = { version = "0.43.0", features = ["serde"] }
|
||||||
libp2p-identity = { version = "0.2.11", features = ["ed25519", "peerid", "rand", "serde"] }
|
libp2p-identity = { version = "0.2.11", features = ["ed25519", "peerid", "rand", "serde"] }
|
||||||
prost = "0.14.1"
|
prost = "0.14.1"
|
||||||
|
prost-types = "0.14.1"
|
||||||
sea-orm.workspace = true
|
sea-orm.workspace = true
|
||||||
sea-orm-migration.workspace = true
|
sea-orm-migration.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
@ -35,7 +36,7 @@ tonic-prost = "0.14.0"
|
||||||
tracing = "0.1.41"
|
tracing = "0.1.41"
|
||||||
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
prost-types = "0.14.1"
|
url.workspace = true
|
||||||
sysinfo = "0.37.0"
|
sysinfo = "0.37.0"
|
||||||
whoami = "1.6.1"
|
whoami = "1.6.1"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum ConfigError {
|
pub enum ConfigError {
|
||||||
#[error("missing config: {0}")]
|
#[error("missing config: {0}")]
|
||||||
|
|
@ -7,5 +9,7 @@ pub enum ConfigError {
|
||||||
#[error("Toml Deserialization Error")]
|
#[error("Toml Deserialization Error")]
|
||||||
TomlDerialization(#[from] toml::de::Error),
|
TomlDerialization(#[from] toml::de::Error),
|
||||||
#[error("Toml Serialization Error")]
|
#[error("Toml Serialization Error")]
|
||||||
TomlSerialization(#[from] toml::ser::Error),
|
TomlSerialization(#[from] toml::ser::Error),
|
||||||
|
#[error("Invalid url: {0}")]
|
||||||
|
InvalidUrl(Url)
|
||||||
}
|
}
|
||||||
|
|
@ -1,25 +1,28 @@
|
||||||
use std::{net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, path::PathBuf, str::FromStr};
|
use std::{net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, path::PathBuf, str::FromStr};
|
||||||
#[cfg(feature="cli")]
|
#[cfg(feature="cli")]
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
|
use url::Url;
|
||||||
use crate::{config::PartialConfig, utils::{emptiable::Emptiable, mergeable::Mergeable}};
|
use crate::{config::PartialConfig, utils::{emptiable::Emptiable, mergeable::Mergeable}};
|
||||||
use libp2p::mdns::Config;
|
use libp2p::mdns::Config;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::config::error::ConfigError;
|
use crate::config::error::ConfigError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
static DEFAULT_SOCKET_PATH: &str = "caretta.sock";
|
static DEFAULT_PORT: u16 = 54321;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RpcConfig {
|
pub struct RpcConfig {
|
||||||
pub socket_path: PathBuf,
|
pub endpoint_url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<PartialRpcConfig> for RpcConfig {
|
impl TryFrom<PartialRpcConfig> for RpcConfig {
|
||||||
type Error = ConfigError;
|
type Error = ConfigError;
|
||||||
fn try_from(config: PartialRpcConfig) -> Result<Self, Self::Error> {
|
fn try_from(config: PartialRpcConfig) -> Result<Self, Self::Error> {
|
||||||
Ok(Self{
|
Ok(Self{
|
||||||
socket_path: config.socket_path.ok_or(ConfigError::MissingConfig("port".to_string()))?,
|
endpoint_url: config.endpoint_url.ok_or(ConfigError::MissingConfig("endpoint".to_string()))?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -27,21 +30,21 @@ impl TryFrom<PartialRpcConfig> for RpcConfig {
|
||||||
#[cfg_attr(feature="cli", derive(Args))]
|
#[cfg_attr(feature="cli", derive(Args))]
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
|
||||||
pub struct PartialRpcConfig {
|
pub struct PartialRpcConfig {
|
||||||
pub socket_path: Option<PathBuf>,
|
pub endpoint_url: Option<Url>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialRpcConfig {
|
impl PartialRpcConfig {
|
||||||
#[cfg(not(target_os="ios"))]
|
#[cfg(not(any(all(target_os="ios", target_abi="sim"), target_os="windows")))]
|
||||||
pub fn default(app_name: &'static str) -> Self {
|
pub fn default(app_name: &'static str) -> Self {
|
||||||
let username = whoami::username();
|
let username = whoami::username();
|
||||||
Self{
|
Self{
|
||||||
socket_path: Some(std::env::temp_dir().join(username).join(String::from(app_name) + ".sock")),
|
endpoint_url: Some(Url::parse(&(String::from("unix://") + std::env::temp_dir().join(username).join(String::from(app_name) + ".sock").to_str().unwrap())).unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(target_os="ios")]
|
#[cfg(any(all(target_os="ios", target_abi="sim"), target_os="windows"))]
|
||||||
pub fn default(app_name: &'static str) -> Self {
|
pub fn default(app_name: &'static str) -> Self {
|
||||||
Self{
|
Self{
|
||||||
socket_path: Some(std::env::temp_dir().join(String::from(app_name) + ".sock")),
|
endpoint_url: Some(Url::parse("http://127.0.0.1:54321").unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,26 +52,26 @@ impl PartialRpcConfig {
|
||||||
impl Emptiable for PartialRpcConfig {
|
impl Emptiable for PartialRpcConfig {
|
||||||
fn empty() -> Self {
|
fn empty() -> Self {
|
||||||
Self {
|
Self {
|
||||||
socket_path: None,
|
endpoint_url: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.socket_path.is_none()
|
self.endpoint_url.is_none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RpcConfig> for PartialRpcConfig {
|
impl From<RpcConfig> for PartialRpcConfig {
|
||||||
fn from(source: RpcConfig) -> Self {
|
fn from(source: RpcConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
socket_path: Some(source.socket_path),
|
endpoint_url: Some(source.endpoint_url),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mergeable for PartialRpcConfig {
|
impl Mergeable for PartialRpcConfig {
|
||||||
fn merge(&mut self, other: Self) {
|
fn merge(&mut self, other: Self) {
|
||||||
if let Some(x) = other.socket_path {
|
if let Some(x) = other.endpoint_url {
|
||||||
self.socket_path = Some(x);
|
self.endpoint_url = Some(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::{path::PathBuf, sync::LazyLock};
|
||||||
use sea_orm::{sea_query::{FromValueTuple, IntoValueTuple, ValueType}, ActiveModelBehavior, ActiveModelTrait, ColumnTrait, Condition, DatabaseConnection, EntityTrait, IntoActiveModel, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, Value};
|
use sea_orm::{sea_query::{FromValueTuple, IntoValueTuple, ValueType}, ActiveModelBehavior, ActiveModelTrait, ColumnTrait, Condition, DatabaseConnection, EntityTrait, IntoActiveModel, ModelTrait, PrimaryKeyToColumn, PrimaryKeyTrait, Value};
|
||||||
use sea_orm::QueryFilter;
|
use sea_orm::QueryFilter;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
use url::Url;
|
||||||
use crate::{ config::{Config, PartialConfig, PartialP2pConfig, PartialRpcConfig, RpcConfig, StorageConfig}, message::Message};
|
use crate::{ config::{Config, PartialConfig, PartialP2pConfig, PartialRpcConfig, RpcConfig, StorageConfig}, message::Message};
|
||||||
|
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
@ -20,7 +21,7 @@ pub static TEST_CONFIG: LazyLock<Config> = LazyLock::new(|| {
|
||||||
cache_directory: cache_dir,
|
cache_directory: cache_dir,
|
||||||
},
|
},
|
||||||
rpc: RpcConfig{
|
rpc: RpcConfig{
|
||||||
socket_path: test_dir.join("socket.sock"),
|
endpoint_url: Url::parse(&(String::from("unix://") + test_dir.join("socket.sock").to_str().unwrap())).unwrap(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,3 +13,4 @@ libp2p.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
tokio-stream = { version = "0.1.17", features = ["net"] }
|
tokio-stream = { version = "0.1.17", features = ["net"] }
|
||||||
tonic.workspace = true
|
tonic.workspace = true
|
||||||
|
url.workspace = true
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use caretta_sync::{
|
use caretta_sync::{
|
||||||
config::P2pConfig,
|
config::P2pConfig,
|
||||||
proto::cached_peer_service_server::CachedPeerServiceServer,
|
proto::cached_peer_service_server::CachedPeerServiceServer,
|
||||||
|
|
@ -43,21 +45,35 @@ impl ServerTrait for Server {
|
||||||
|
|
||||||
async fn serve_rpc<T>(config: &T) -> Result<(), caretta_sync::error::Error>
|
async fn serve_rpc<T>(config: &T) -> Result<(), caretta_sync::error::Error>
|
||||||
where T: AsRef<caretta_sync::config::RpcConfig> {
|
where T: AsRef<caretta_sync::config::RpcConfig> {
|
||||||
let path = config.as_ref().socket_path.clone();
|
let url = config.as_ref().endpoint_url.clone();
|
||||||
if let Some(x) = path.parent() {
|
let router = tonic::transport::Server::builder()
|
||||||
if !x.exists() {
|
.add_service(CachedPeerServiceServer::new(CachedPeerService::default()));
|
||||||
std::fs::create_dir_all(x).expect("Failed to create directory for socket file!");
|
match url.scheme() {
|
||||||
|
"unix" => {
|
||||||
|
let path = PathBuf::from(url.path());
|
||||||
|
if let Some(x) = path.parent() {
|
||||||
|
if !x.exists() {
|
||||||
|
std::fs::create_dir_all(x).expect("Failed to create directory for socket file!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if path.exists() {
|
||||||
|
std::fs::remove_file(&path).expect("Failed to remove existing socket file!")
|
||||||
|
}
|
||||||
|
let uds = UnixListener::bind(path).unwrap();
|
||||||
|
let uds_stream = UnixListenerStream::new(uds);
|
||||||
|
|
||||||
|
router.serve_with_incoming(uds_stream)
|
||||||
|
.await.unwrap();
|
||||||
|
},
|
||||||
|
"http" => {
|
||||||
|
let host = url.socket_addrs(|| None).expect("http endpoint should have host address and port").pop().unwrap();
|
||||||
|
|
||||||
|
router.serve(host).await.unwrap();
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
Err(caretta_sync::error::Error::Config(caretta_sync::config::ConfigError::InvalidUrl(url)))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if path.exists() {
|
|
||||||
std::fs::remove_file(&path).expect("Failed to remove existing socket file!")
|
|
||||||
}
|
|
||||||
let uds = UnixListener::bind(path).unwrap();
|
|
||||||
let uds_stream = UnixListenerStream::new(uds);
|
|
||||||
tonic::transport::Server::builder()
|
|
||||||
.add_service(CachedPeerServiceServer::new(CachedPeerService::default()))
|
|
||||||
.serve_with_incoming(uds_stream)
|
|
||||||
.await.unwrap();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,16 +30,14 @@ pub async fn init_config() {
|
||||||
let mut default = PartialConfig::default(APP_NAME);
|
let mut default = PartialConfig::default(APP_NAME);
|
||||||
default.merge(config);
|
default.merge(config);
|
||||||
let config2 : Config = default.try_into().unwrap();
|
let config2 : Config = default.try_into().unwrap();
|
||||||
Server::serve_all(&config2).await;
|
Server::serve_all(&config2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bevy_main]
|
#[bevy_main]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
||||||
//init_config();
|
init_config();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
app.add_plugins(
|
app.add_plugins(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue