Sending messages
The core of our application has been built. All that's left is to add a UI
that takes user input, creates a DchatMsg
and sends it over the network.
Let's start by creating a send()
function inside Dchat
. This will
introduce us to a new p2p method that is essential to our chat app:
p2p.broadcast()
.
async fn send(&self, msg: String) -> Result<()> {
let dchatmsg = DchatMsg { msg };
self.p2p.broadcast(dchatmsg).await?;
Ok(())
}
We pass a String
called msg that will be taken from user input. We use
this input to initialize a message of the type DchatMsg
that the network
can now support. Finally, we pass the message into p2p.broadcast()
.
Here's what happens under the hood:
pub async fn broadcast<M: Message + Clone>(&self, message: M) -> Result<()> {
let chans = self.channels.lock().await;
let iter = chans.values();
let mut futures = FuturesUnordered::new();
for channel in iter {
futures.push(channel.send(message.clone()).map_err(|e| {
format!(
"P2P::broadcast: Broadcasting message to {} failed: {}",
channel.address(),
e
)
}));
}
if futures.is_empty() {
error!(target: "net::p2p::broadcast()", "P2P::broadcast: No connected channels found");
return Ok(())
}
while let Some(entry) = futures.next().await {
if let Err(e) = entry {
error!(target: "net::p2p::broadcast()", "{}", e);
}
}
Ok(())
}
This is pretty straightforward: broadcast()
takes a generic Message
type
and sends it across all the channels that our node has access to.
All that's left to do is to create a UI.