dchat: renamed dchat to dchatd and add placeholder dchat-cli

This commit is contained in:
lunar-mining
2023-12-14 09:12:53 +01:00
parent b0899f8f4b
commit f8dc600fd9
9 changed files with 167 additions and 76 deletions

View File

@@ -0,0 +1,90 @@
# This file is part of DarkFi (https://dark.fi)
#
# Copyright (C) 2020-2023 Dyne.org foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import asyncio, json, random, sys, time
# TODO: this cli is currently unimplemented
class JsonRpc:
async def start(self, server, port):
reader, writer = await asyncio.open_connection(server, port)
self.reader = reader
self.writer = writer
async def stop(self):
self.writer.close()
await self.writer.wait_closed()
async def _make_request(self, method, params):
ident = random.randint(0, 2**16)
print(ident)
request = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": ident,
}
message = json.dumps(request) + "\n"
self.writer.write(message.encode())
await self.writer.drain()
data = await self.reader.readline()
message = data.decode().strip()
response = json.loads(message)
print(response)
return response
async def _subscribe(self, method, params):
ident = random.randint(0, 2**16)
request = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": ident,
}
message = json.dumps(request) + "\n"
self.writer.write(message.encode())
await self.writer.drain()
print("Subscribed")
async def ping(self):
return await self._make_request("ping", [])
async def dnet_switch(self, state):
return await self._make_request("dnet.switch", [state])
async def dnet_subscribe_events(self):
return await self._subscribe("dnet.subscribe_events", [])
async def main(argv):
# TODO: Rpc port should be command line flag
# e.g. dchat 1066
rpc = JsonRpc()
while True:
try:
await rpc.start("localhost", 26660)
break
except OSError:
pass
await rpc.stop()
asyncio.run(main(sys.argv))

View File

@@ -1,33 +1,36 @@
[package]
name = "dchat"
name = "dchatd"
version = "0.4.2"
homepage = "https://dark.fi"
description = "Demo chat app used to document DarkFi networking code"
description = "Simple chat app p2p daemon used to document DarkFi networking code"
authors = ["Dyne.org foundation <foundation@dyne.org>"]
repository = "https://github.com/darkrenaissance/darkfi"
license = "AGPL-3.0-only"
edition = "2021"
# ANCHOR: darkfi
[dependencies]
darkfi = {path = "../../", features = ["net", "toml", "system", "async-daemonize", "rpc"]}
darkfi-serial = {path = "../../src/serial"}
# ANCHOR_END: darkfi
# ANCHOR: dependencies
async-trait = "0.1.74"
log = "0.4.20"
url = "2.5.0"
[dependencies]
# darkfi
darkfi = {path = "../../../", features = ["net", "toml", "system", "async-daemonize", "rpc"]}
darkfi-serial = {path = "../../../src/serial"}
# Daemon
# daemon
easy-parallel = "3.3.1"
signal-hook-async-std = "0.2.2"
signal-hook = "0.3.17"
simplelog = "0.12.1"
smol = "1.3.0"
# Arg parsing
serde = {version = "1.0.193", features = ["derive"]}
# arg parsing
serde = {version = "1.0.192", features = ["derive"]}
structopt = "0.3.26"
structopt-toml = "0.5.1"
# misc
async-trait = "0.1.74"
log = "0.4.20"
url = "2.4.1"
# ANCHOR_END: dependencies

View File

@@ -1,6 +1,6 @@
# Dchat
A demo chat program to document DarkFi net
A simple chat program to document DarkFi net
code. Tutorial can be found in the [DarkFi
book](https://darkrenaissance.github.io/darkfi/learn/writing-a-p2p-app.html).

View File

@@ -10,3 +10,5 @@
## Seed nodes to connect to. Required for inbound and outbound nodes.
seeds=["tcp://127.0.0.1:55555"]
## Outbound connect slots. Required for outbound nodes.
outbound_connections = 5

View File

@@ -29,7 +29,6 @@ use darkfi::{
server::{listen_and_serve, RequestHandler},
},
system::{StoppableTask, StoppableTaskPtr},
util::path::get_config_path,
Error, Result,
};
@@ -45,8 +44,8 @@ pub mod dchatmsg;
pub mod protocol_dchat;
pub mod rpc;
const CONFIG_FILE: &str = "dchat_config.toml";
const CONFIG_FILE_CONTENTS: &str = include_str!("../dchat_config.toml");
const CONFIG_FILE: &str = "dchatd_config.toml";
const CONFIG_FILE_CONTENTS: &str = include_str!("../dchatd_config.toml");
// ANCHOR: args
#[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)]
@@ -98,68 +97,65 @@ impl Dchat {
// ANCHOR: main
async_daemonize!(realmain);
async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
let cfg_path = get_config_path(args.config, CONFIG_FILE)?;
let _toml_contents = std::fs::read_to_string(cfg_path)?;
let p2p = net::P2p::new(args.net.into(), ex.clone()).await;
// ANCHOR: dnet
info!("Starting dnet subs task");
let dnet_sub = JsonSubscriber::new("dnet.subscribe_events");
let dnet_sub_ = dnet_sub.clone();
let p2p_ = p2p.clone();
let dnet_task = StoppableTask::new();
dnet_task.clone().start(
async move {
let dnet_sub = p2p_.dnet_subscribe().await;
loop {
let event = dnet_sub.receive().await;
debug!("Got dnet event: {:?}", event);
dnet_sub_.notify(vec![event.into()].into()).await;
}
},
|res| async {
match res {
Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
Err(e) => panic!("{}", e),
}
},
Error::DetachedTaskStopped,
ex.clone(),
);
// ANCHOR_end: dnet
// // ANCHOR: dnet
// info!("Starting dnet subs task");
// let dnet_sub = JsonSubscriber::new("dnet.subscribe_events");
// let dnet_sub_ = dnet_sub.clone();
// let p2p_ = p2p.clone();
// let dnet_task = StoppableTask::new();
// dnet_task.clone().start(
// async move {
// let dnet_sub = p2p_.dnet_subscribe().await;
// loop {
// let event = dnet_sub.receive().await;
// debug!("Got dnet event: {:?}", event);
// dnet_sub_.notify(vec![event.into()].into()).await;
// }
// },
// |res| async {
// match res {
// Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
// Err(e) => panic!("{}", e),
// }
// },
// Error::DetachedTaskStopped,
// ex.clone(),
// );
// // ANCHOR_end: dnet
// ANCHOR: rpc
info!("Starting JSON-RPC server on port {}", args.rpc_listen);
let msgs: DchatMsgsBuffer = Arc::new(Mutex::new(vec![DchatMsg { msg: String::new() }]));
let rpc_connections = Mutex::new(HashSet::new());
let dchat = Arc::new(Dchat::new(p2p.clone(), msgs.clone(), rpc_connections, dnet_sub));
let _ex = ex.clone();
// // ANCHOR: rpc
// info!("Starting JSON-RPC server on port {}", args.rpc_listen);
// let msgs: DchatMsgsBuffer = Arc::new(Mutex::new(vec![DchatMsg { msg: String::new() }]));
// let rpc_connections = Mutex::new(HashSet::new());
// let dchat = Arc::new(Dchat::new(p2p.clone(), msgs.clone(), rpc_connections, dnet_sub));
// let _ex = ex.clone();
let rpc_task = StoppableTask::new();
rpc_task.clone().start(
listen_and_serve(args.rpc_listen, dchat.clone(), None, ex.clone()),
|res| async move {
match res {
Ok(()) | Err(Error::RpcServerStopped) => dchat.stop_connections().await,
Err(e) => error!("Failed stopping JSON-RPC server: {}", e),
}
},
Error::RpcServerStopped,
ex.clone(),
);
// ANCHOR_end: rpc
// let rpc_task = StoppableTask::new();
// rpc_task.clone().start(
// listen_and_serve(args.rpc_listen, dchat.clone(), None, ex.clone()),
// |res| async move {
// match res {
// Ok(()) | Err(Error::RpcServerStopped) => dchat.stop_connections().await,
// Err(e) => error!("Failed stopping JSON-RPC server: {}", e),
// }
// },
// Error::RpcServerStopped,
// ex.clone(),
// );
// // ANCHOR_end: rpc
// ANCHOR: register_protocol
info!("Registering Dchat protocol");
let registry = p2p.protocol_registry();
registry
.register(!net::session::SESSION_SEED, move |channel, _p2p| {
let msgs_ = msgs.clone();
async move { ProtocolDchat::init(channel, msgs_).await }
})
.await;
// ANCHOR_END: register_protocol
// // ANCHOR: register_protocol
// info!("Registering Dchat protocol");
// let registry = p2p.protocol_registry();
// registry
// .register(!net::session::SESSION_SEED, move |channel, _p2p| {
// let msgs_ = msgs.clone();
// async move { ProtocolDchat::init(channel, msgs_).await }
// })
// .await;
// // ANCHOR_END: register_protocol
// ANCHOR: p2p_start
info!("Starting P2P network");
@@ -174,11 +170,11 @@ async fn realmain(args: Args, ex: Arc<smol::Executor<'static>>) -> Result<()> {
info!("Stopping P2P network");
p2p.stop().await;
info!("Stopping JSON-RPC server");
rpc_task.stop().await;
dnet_task.stop().await;
//info!("Stopping JSON-RPC server");
//rpc_task.stop().await;
//dnet_task.stop().await;
info!("Shut down successfully");
//info!("Shut down successfully");
// ANCHOR_END: shutdown
Ok(())
}