(2) Peer To Peer Chat Tutorial in Go
- Jason Fantl
- Oct 19, 2022
- 2 min read
Updated: Oct 22, 2022
Concept
Time to add flood filling to the network! So how will this work? Well, when a node wants to send a message, their only option is to send it out to all their connected nodes, which of course is not enough, the message needs to continue out and fill the network. This means that when we as a node receive a message, we should pass it on to all of our connections so the message can pass on to more people. A small issue arises: whenever we have a cycle (A sends to B, then B to C, and C to A) we end up in an endless loop where the message gets passed around forever. In order to avoid this, we have each node "remember" any recent messages so that if they receive a message twice, they can just ignore it.
One potential issue with ignoring repeated messages is that people can't send the same message twice, which they may want to do. In order to avoid this we will use a unique identifier for each message. Now we only avoid re-sending a message with the same ID, this way we can send the same text multiple times and avoid cycles.

How much wasted bandwidth?
It can be interesting to consider how much bandwidth our network is wasting. Let's consider a network of N nodes, each with D connections, and we don't care how they're connected (except that there exists a path between every node). A person sends out a message over D connections, each node that receives the message sends it to everyone they know (including the person they just received it from, inefficient, but simplifies calculation with minimal impact), and so on. This means every node receives the same message D times (think through why). Each person (except the original sender) only needed to receive it once, a total of N-1 transmits of the message. We are transmitting the message N*D times in the network, that's a waste of N*D-N = N(D-1). If we could coordinate between everyone, we could calculate a minimum spanning tree and send the message only N-1 times, that would mean zero bandwidth waste! But we want a flexible network, so we won't be tracking the network topology and calculating the minimum spanning tree. But it is interesting to consider how you might structure a network such that you can minimize bandwidth waste.
Code
We will modify the node.go file we used in the previous tutorial. There are a few differences: Instead of just sending text we now send a 'Message' object containing both the message text and a unique identifier. We keep track of our previously announced messages, which then determine if we should announce a newly received messages.
Now open up three terminals and run node.go with
go run node.go
Then connect the first to the second, and second to the third. Send a message on the first, it should appear on the second and third as well. That means the message was passed on to fill the network.
Clean up
Our file is getting a bit large, so I'm going to try and organize the code across different files. None of the code is changing, we're just trying to make it more manageable. For now, I best understand the code as split between main.go, connections.go, and messages.go.
main.go
connections.go
messages.go
Now when we want to run the code we need to tell Go which files to use, so we run it with
go run main.go connections.go messaging.go
Next
We want people to automatically join the network and preferably have multiple connections at once in case one or two disconnect.
Comments