Sfoglia il codice sorgente

dchat: fixed links + added missing info

lunar-mining 4 anni fa
parent
commit
22444e04c6

+ 7 - 0
doc/src/learn/dchat/creating-dchat/creating-dchat.md

@@ -4,3 +4,10 @@ Now that we've deployed a local version of the p2p network, we can start
 creating a custom protocol and message types that dchat will use to
 creating a custom protocol and message types that dchat will use to
 send and receive messages across the network.
 send and receive messages across the network.
 
 
+This section will cover:
+
+* The Message type
+* Protocols and the protocol registry
+* The message subsystem
+* Message subscriptions
+* Channels

+ 103 - 0
doc/src/learn/dchat/creating-dchat/protocol-dchat.md

@@ -1 +1,104 @@
 # ProtocolDchat
 # ProtocolDchat
+
+Let's start tying these concepts together. We'll define a struct called
+ProtocolDchat that contains a MessageSubscription to Dchatmsg and a
+pointer to the ProtocolJobsManager. We'll also include the DchatmsgsBuffer
+in the struct as it will come in handy later on.
+
+```
+use darkfi::net;
+
+use crate::dchatmsg::{Dchatmsg, DchatmsgsBuffer};
+
+pub struct ProtocolDchat {
+    jobsman: net::ProtocolJobsManagerPtr,
+    msg_sub: net::MessageSubscription<Dchatmsg>,
+    msgs: DchatmsgsBuffer,
+}
+```
+
+Next we'll implement the trait ProtocolBase. ProtocolBase requires two
+functions, start() and name(). In start() we will start up the Protocol
+Jobs Manager. name() will return a str of the protocol name.
+
+```
+use async_executor::Executor;
+use async_std::sync::Arc;
+use async_trait::async_trait;
+use darkfi::{net, Result};
+
+use crate::dchatmsg::{Dchatmsg, DchatmsgsBuffer};
+
+#[async_trait]
+impl net::ProtocolBase for ProtocolDchat {
+    async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
+        self.jobsman.clone().start(executor.clone());
+        Ok(())
+    }
+
+    fn name(&self) -> &'static str {
+        "ProtocolDchat"
+    }
+}
+```
+
+Once that's done, we'll need to create a ProtocolDchat constructor that
+we will pass to the ProtocolRegistry to register our protocol. The
+constructor takes a pointer to channel which it uses to invoke the
+Message Subsystem and add Dchatmsg as to the list of dispatchers. Next,
+we'll create a message subscription to Dchatmsg using the method
+subscribe_msg().
+
+We'll also initialize the Protocol Jobs Manager and finally return a
+pointer to the protocol.
+
+```
+impl ProtocolDchat {
+    pub async fn init(channel: net::ChannelPtr, msgs: DchatmsgsBuffer) -> net::ProtocolBasePtr {
+        let message_subsytem = channel.get_message_subsystem();
+        message_subsytem.add_dispatch::<Dchatmsg>().await;
+
+        let msg_sub = channel
+            .subscribe_msg::<Dchatmsg>()
+            .await
+            .expect("Missing DchatMsg dispatcher!");
+
+        Arc::new(Self {
+            jobsman: net::ProtocolJobsManager::new("ProtocolDchat", channel.clone()),
+            msg_sub,
+            msgs,
+        })
+    }
+}
+```
+
+We're nearly there. But right now the protocol doesn't actually do
+anything. Let's write a method called handle_receive_msg() which receives
+a message on our message subscription and adds it to DchatmsgsBuffer.
+ 
+Put this inside the ProtocolDchat implementation:
+
+```
+async fn handle_receive_msg(self: Arc<Self>) -> Result<()> {
+    while let Ok(msg) = self.msg_sub.receive().await {
+        let msg = (*msg).to_owned();
+        self.msgs.lock().await.push(msg);
+    }
+
+    Ok(())
+}
+```
+
+As a final step, let's add that task to the jobs manager that is invoked
+in start():
+
+```
+async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
+    self.jobsman.clone().start(executor.clone());
+    self.jobsman
+        .clone()
+        .spawn(self.clone().handle_receive_msg(), executor.clone())
+        .await;
+    Ok(())
+}
+```

+ 18 - 12
doc/src/learn/dchat/creating-dchat/protocols.md

@@ -8,20 +8,20 @@ are automatically activated when nodes connect to eachother on the
 p2p network. Here are examples of two protocols that every node runs
 p2p network. Here are examples of two protocols that every node runs
 continuously in the background:
 continuously in the background:
 
 
-[ProtocolPing](../../../src/net/protocol/protocol_ping.rs): sends ping,
-receives pong
-[ProtocolAddress](../../../src/net/protocol/protocol_address.rs): receives
-a get_address message, sends an address message
+[ProtocolPing](https://github.com/darkrenaissance/darkfi/blob/master/src/net/protocol/protocol_ping.rs):
+sends ping, receives pong
+[ProtocolAddress](https://github.com/darkrenaissance/darkfi/blob/master/src/net/protocol/protocol_address.rs):
+receives a get_address message, sends an address message
 
 
 Under the hood, these protocols have a few similarities:
 Under the hood, these protocols have a few similarities:
 
 
 1. They create a subscription to a message type, such as Ping and Pong.
 1. They create a subscription to a message type, such as Ping and Pong.
-2. They implement [ProtocolBase](../../../src/net/protocol/protocol_base.rs),
+2. They implement [ProtocolBase](https://github.com/darkrenaissance/darkfi/blob/master/src/net/protocol/protocol_base.rs),
 DarkFi's generic protocol trait.
 DarkFi's generic protocol trait.
 3. They run asynchronously using the
 3. They run asynchronously using the
-[ProtocolJobsManager](../../../src/net/protocol/protocol_jobs_manager.rs).
-4. They hold a pointer to [Channel](../../../src/net/channel.rs) which
-invokes the [MessageSubsystem](../../../src/net/message_subscriber).
+[ProtocolJobsManager](https://github.com/darkrenaissance/darkfi/blob/master/src/net/protocol/protocol_jobs_manager.rs).
+4. They hold a pointer to [Channel](https://github.com/darkrenaissance/darkfi/blob/master/src/net/channel.rs) which
+invokes the [MessageSubsystem](https://github.com/darkrenaissance/darkfi/blob/master/src/net/message_subscriber.rs#L170).
 
 
 This introduces several generic interfaces that we must use to build
 This introduces several generic interfaces that we must use to build
 our custom protocol. In particular:
 our custom protocol. In particular:
@@ -36,19 +36,25 @@ can send and receive custom messages on the p2p network.
 
 
 A subscription to a message type. 
 A subscription to a message type. 
 
 
-3. The Protocol Registry 
+3. Channel
+
+A channel is an async connection for communication between nodes. It is
+also a powerful interface that exposes methods to the Message Subsystem
+and implements message subscriptions.  Channel also contains a weak
+pointer to its parent, Session.
+
+4. The Protocol Registry 
 
 
 ProtocolRegistry takes any kind of generic protocol and initializes it. We
 ProtocolRegistry takes any kind of generic protocol and initializes it. We
 use it through the method register() which passes a protocol constructor
 use it through the method register() which passes a protocol constructor
 and a session bitflag which determines which sessions (outbound, inbound,
 and a session bitflag which determines which sessions (outbound, inbound,
 or seed) will run our protocol.
 or seed) will run our protocol.
 
 
-4. ProtocolJobsManager
+5. ProtocolJobsManager
 
 
 An asynchronous job manager that spawns and stops tasks created by
 An asynchronous job manager that spawns and stops tasks created by
 protocols across the network.
 protocols across the network.
 
 
-5. ProtocolBase
+6. ProtocolBase
 
 
 A generic protocol trait that all protocols must implement.
 A generic protocol trait that all protocols must implement.
-

+ 1 - 1
doc/src/learn/dchat/dchat.md

@@ -16,5 +16,5 @@ the p2p network, in particular:
 * Creating and subscribing to a custom message type.
 * Creating and subscribing to a custom message type.
 
 
 The source code for this tutorial can be found at
 The source code for this tutorial can be found at
-[example/dchat](../../../example/dchat).
+[example/dchat](https://github.com/darkrenaissance/darkfi/tree/master/example/dchat).
 
 

+ 3 - 3
doc/src/learn/dchat/local-deployment/creating-and-running.md

@@ -45,7 +45,7 @@ async fn start(&self, ex: Arc<Executor<'_>>) -> Result<()> {
 
 
 Let's take a quick look at the underlying p2p methods we're using here.
 Let's take a quick look at the underlying p2p methods we're using here.
 
 
-This is [start()](../../../src/net/p2p.rs):
+This is [start()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L129):
 
 
 ```
 ```
 pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
 pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
@@ -66,7 +66,7 @@ pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
 ```
 ```
 
 
 start() changes the P2pState to P2pState::Start and runs a [seed
 start() changes the P2pState to P2pState::Start and runs a [seed
-session](../../../src/net/session/seed_session.rs).
+session](https://github.com/darkrenaissance/darkfi/blob/master/src/net/session/seed_session.rs).
 
 
 This loops through the seed addresses specified in our Settings and
 This loops through the seed addresses specified in our Settings and
 tries to connect to them. The seed session either connects successfully,
 tries to connect to them. The seed session either connects successfully,
@@ -76,7 +76,7 @@ If a seed node connects successfully, it runs a version exchange protocol,
 stores the channel in the p2p list of channels, and disconnects, removing
 stores the channel in the p2p list of channels, and disconnects, removing
 the channel from the channel list.
 the channel from the channel list.
 
 
-This is [run()](../../../src/net/p2p.rs):
+This is [run()](https://github.com/darkrenaissance/darkfi/blob/master/src/net/p2p.rs#L157):
 
 
 ```
 ```
 pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
 pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {

+ 7 - 6
doc/src/learn/dchat/local-deployment/inbound-and-outbound.md

@@ -11,12 +11,13 @@ connections. A seed node is used when connecting to the network: it is
 a special kind of inbound node that gets connected to, sends over a list
 a special kind of inbound node that gets connected to, sends over a list
 of addresses and disconnects again.
 of addresses and disconnects again.
 
 
-The behavior of the different kinds of nodes is defined in what is
-called a [Session](../../../src/net/session/mod.rs). Session is a trait
-that outbound, inbound, manual and seed nodes all implement. Session
-implementations expose methods such as stopping and starting a channel,
-accepting connections (inbound nodes) or making connections (outbound
-nodes).
+The behavior of the different
+kinds of nodes is defined in what is called a
+[Session](https://github.com/darkrenaissance/darkfi/blob/master/src/net/session/mod.rs#L93).
+Session is a trait that outbound, inbound, manual and seed nodes all
+implement. Session implementations expose methods such as stopping and
+starting a channel, accepting connections (inbound nodes) or making
+connections (outbound nodes).
 
 
 On production-ready software, you would usually configure your node
 On production-ready software, you would usually configure your node
 using a config file or command line inputs. On dchat we are keeping
 using a config file or command line inputs. On dchat we are keeping

+ 1 - 1
doc/src/learn/dchat/local-deployment/writing-a-daemon.md

@@ -47,5 +47,5 @@ but soon we'll run dchat inside this block.
 Note: DarkFi includes a macro called async_daemonize that is used by
 Note: DarkFi includes a macro called async_daemonize that is used by
 DarkFi binaries to minimize boilerplate in the repo.  To keep things
 DarkFi binaries to minimize boilerplate in the repo.  To keep things
 simple we will ignore this macro for the purpose of this tutorial.  But
 simple we will ignore this macro for the purpose of this tutorial.  But
-check it out if you are curious: [util/cli.rs](../../../src/util/cli.rs).
+check it out if you are curious: [util/cli.rs](https://github.com/darkrenaissance/darkfi/blob/master/src/util/cli.rs#L154).