فهرست منبع

dchat: fixed links + added missing info

lunar-mining 4 سال پیش
والد
کامیت
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
 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
+
+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
 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:
 
 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.
 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
 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. 
 
-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
 use it through the method register() which passes a protocol constructor
 and a session bitflag which determines which sessions (outbound, inbound,
 or seed) will run our protocol.
 
-4. ProtocolJobsManager
+5. ProtocolJobsManager
 
 An asynchronous job manager that spawns and stops tasks created by
 protocols across the network.
 
-5. ProtocolBase
+6. ProtocolBase
 
 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.
 
 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.
 
-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<()> {
@@ -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
-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
 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
 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<()> {

+ 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
 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
 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
 DarkFi binaries to minimize boilerplate in the repo.  To keep things
 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).