rust-talk
A peer-to-peer chat CLI application built with Rust and libp2p.
Features
- Decentralized P2P messaging: No central server required
- Automatic peer discovery: Uses mDNS for local network discovery
- Manual peer connection: Connect to specific peers by address
- Encrypted communication: Uses Noise protocol for transport encryption
- Real-time messaging: Messages are broadcast instantly to all connected peers
Installation
Clone the repository and build the project:
git clone <repository-url>
cd rust-talk
cargo build --releaseUsage
Basic Usage
Start the first instance:
cargo runYou'll see output like:
Local peer id: 12D3KooWA1B2C3D4...
[Swarm] Listening on /ip4/0.0.0.0/tcp/12345
For localhost: /ip4/127.0.0.1/tcp/12345
Chat started! Type messages and press enter to send.
To connect another peer, run: cargo run -- <address>
Connecting Peers on Localhost
To test on the same machine, copy the localhost address from the first instance and start a second instance:
cargo run -- /ip4/127.0.0.1/tcp/12345Replace 12345 with the actual port number from the first instance.
Connecting Peers on Local Network
For peers on the same local network:
- Start an instance on each machine with
cargo run - Peers should automatically discover each other via mDNS
- Alternatively, use the manual connection method with the network IP address:
cargo run -- /ip4/192.168.1.100/tcp/12345Sending Messages
Once connected, simply type your message and press Enter. Messages will appear on all connected peers.
How It Works
Architecture
The application uses libp2p with the following components:
- Transport: TCP with Noise encryption and Yamux stream multiplexing
- Peer Discovery: mDNS for automatic local network peer discovery
- Messaging: Gossipsub pub/sub protocol for message broadcasting
- Keep-alive: Ping protocol to maintain connections
- Runtime: Tokio for async execution
Network Behavior
The ChatBehaviour combines three libp2p protocols:
- Gossipsub: Handles message publishing and subscription to the "chat" topic
- mDNS: Automatically discovers peers on the local network
- Ping: Keeps connections alive with periodic ping messages
Message Flow
- User types a message and presses Enter
- Message is published to the "chat" topic via Gossipsub
- Gossipsub broadcasts the message to all peers subscribed to the topic
- Other peers receive and display the message
Debug Output
The application includes verbose logging to help understand what's happening:
[mDNS]: Peer discovery events[Swarm]: Connection lifecycle events[Gossipsub]: Subscription and message events
Example Session
Terminal 1:
$ cargo run
Local peer id: 12D3KooWA1B2C3D4E5F6G7H8...
[Swarm] Listening on /ip4/0.0.0.0/tcp/51234
For localhost: /ip4/127.0.0.1/tcp/51234
Chat started! Type messages and press enter to send.
[Swarm] Incoming connection from /ip4/127.0.0.1/tcp/51235
[Swarm] Connection established with 12D3KooWX9Y8Z7...
[Gossipsub] Peer 12D3KooWX9Y8Z7... subscribed to chat
Hello from peer 1!
You: Hello from peer 1!
Peer 12D3KooW: Hello from peer 2!
Terminal 2:
$ cargo run -- /ip4/127.0.0.1/tcp/51234
Local peer id: 12D3KooWX9Y8Z7A6B5C4D3E2...
Dialing peer at /ip4/127.0.0.1/tcp/51234...
[Swarm] Connection established with 12D3KooWA1B2C3D4...
[Gossipsub] Peer 12D3KooWA1B2C3D4... subscribed to chat
Peer 12D3KooW: Hello from peer 1!
Hello from peer 2!
You: Hello from peer 2!
Troubleshooting
Peers not discovering each other on macOS
mDNS discovery may not work for localhost on some systems. Use the manual connection method instead:
- Start the first instance and note the localhost address
- Start the second instance with that address as an argument
Firewall blocking connections
On macOS/Linux, you may need to allow the application through your firewall:
- macOS: System Settings → Network → Firewall
- Linux: Configure iptables/ufw to allow the port
Technical Details
Dependencies
libp2p: P2P networking framework with gossipsub, mDNS, TCP, Noise, Yamux, and Pingtokio: Async runtimefutures: Async stream utilitiesanyhow: Error handling