# 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, 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, executor: Arc>) -> 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::().await; let msg_sub = channel .subscribe_msg::() .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) -> 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, executor: Arc>) -> Result<()> { self.jobsman.clone().start(executor.clone()); self.jobsman .clone() .spawn(self.clone().handle_receive_msg(), executor.clone()) .await; Ok(()) } ```