mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
dchat: renamed dchat to dchatd and add placeholder dchat-cli
This commit is contained in:
90
example/dchat/dchat-cli/main.py
Normal file
90
example/dchat/dchat-cli/main.py
Normal 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))
|
||||
|
||||
@@ -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
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
@@ -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(())
|
||||
}
|
||||
Reference in New Issue
Block a user