use libp2prs_runtime::task;
use std::time::Duration;
#[macro_use]
extern crate lazy_static;
use libp2prs_core::identity::Keypair;
use libp2prs_core::transport::upgrade::TransportUpgrade;
use libp2prs_core::{Multiaddr, PeerId};
use libp2prs_floodsub::{control::Control as Floodsub_Config, floodsub::FloodSub, FloodsubConfig, Topic};
use libp2prs_secio as secio;
use libp2prs_swarm::identify::IdentifyConfig;
use libp2prs_swarm::ping::PingConfig;
use libp2prs_swarm::Swarm;
use libp2prs_tcp::TcpConfig;
use libp2prs_yamux as yamux;
fn main() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
if std::env::args().nth(1) == Some("server".to_string()) {
log::info!("Starting server ......");
run_server();
} else {
log::info!("Starting client ......");
run_client();
}
}
fn setup_swarm(keys: Keypair) -> (Swarm, Floodsub_Config) {
let sec = secio::Config::new(keys.clone());
let mux = yamux::Config::new();
let tu = TransportUpgrade::new(TcpConfig::default(), mux, sec);
let local_peer_id = keys.public().into_peer_id();
let floodsub = FloodSub::new(FloodsubConfig::new(local_peer_id));
let floodsub_control = floodsub.control();
let swarm = Swarm::new(keys.public())
.with_transport(Box::new(tu))
.with_protocol(floodsub)
.with_ping(PingConfig::new().with_unsolicited(true).with_interval(Duration::from_secs(1)))
.with_identify(IdentifyConfig::new(false));
log::info!("Swarm created, local-peer-id={:?}", swarm.local_peer_id());
(swarm, floodsub_control)
}
lazy_static! {
static ref SERVER_KEY: Keypair = Keypair::generate_ed25519_fixed();
static ref FLOODSUB_TOPIC: Topic = Topic::new("chat");
}
#[allow(clippy::empty_loop)]
fn run_server() {
let keys = SERVER_KEY.clone();
let (mut swarm, floodsub_control) = setup_swarm(keys);
let listen_addr: Multiaddr = "/ip4/127.0.0.1/tcp/8086".parse().unwrap();
swarm.listen_on(vec![listen_addr]).unwrap();
swarm.start();
task::block_on(async {
let mut control = floodsub_control.clone();
task::spawn(async move {
let mut sub = control.subscribe(FLOODSUB_TOPIC.clone()).await.unwrap();
loop {
if let Some(msg) = sub.next().await {
log::info!("recived: {:?}", msg.data)
}
}
});
loop {
let mut line = String::new();
let _ = std::io::stdin().read_line(&mut line);
let x: &[_] = &['\r', '\n'];
let msg = line.trim_end_matches(x);
floodsub_control
.clone()
.publish(Topic::new(FLOODSUB_TOPIC.clone()), msg)
.await
.unwrap();
}
});
}
fn run_client() {
let keys = Keypair::generate_secp256k1();
let (swarm, floodsub_control) = setup_swarm(keys);
let mut swarm_control = swarm.control();
let remote_peer_id = PeerId::from_public_key(SERVER_KEY.public());
log::info!("about to connect to {:?}", remote_peer_id);
swarm.start();
task::block_on(async {
swarm_control
.connect_with_addrs(remote_peer_id, vec!["/ip4/127.0.0.1/tcp/8086".parse().unwrap()])
.await
.unwrap();
let mut control = floodsub_control.clone();
task::spawn(async move {
let mut sub = control.subscribe(FLOODSUB_TOPIC.clone()).await.unwrap();
loop {
if let Some(msg) = sub.next().await {
log::info!("recived: {:?}", msg.data)
}
}
});
loop {
let mut line = String::new();
let _ = std::io::stdin().read_line(&mut line);
let x: &[_] = &['\r', '\n'];
let msg = line.trim_end_matches(x);
floodsub_control
.clone()
.publish(Topic::new(FLOODSUB_TOPIC.clone()), msg)
.await
.unwrap();
}
});
}