Sure, here's a comprehensive README for the p2p
package:
The p2p
package provides an easy-to-use library for building peer-to-peer (P2P) applications using libp2p. This package encapsulates the core functionalities needed for creating a P2P network, setting up pubsub messaging, and handling mDNS peer discovery.
- Peer-to-peer communication using libp2p
- Pubsub messaging with GossipSub
- Local peer discovery using mDNS
- Easy-to-use API for joining rooms and publishing messages
To use the p2p
package in your project, you need to import it and ensure you have the necessary dependencies. Add the following to your go.mod
file:
module p2p-sdk
go 1.16
require (
github.com/libp2p/go-libp2p v0.19.1
github.com/libp2p/go-libp2p-core v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.4.1
github.com/libp2p/go-libp2p-discovery v0.5.1
)
Then run:
go mod tidy
First, import the p2p
package in your application:
import "p2p-sdk/p2p"
Initialize the P2P library and join a room:
ctx := context.Background()
// Initialize the P2P library
p2pInstance, err := p2p.NewP2P(ctx)
if err != nil {
panic(err)
}
// Join an event room
nick := "your-nickname"
roomName := "example-room"
room, err := p2pInstance.JoinRoom(ctx, roomName, nick)
if err != nil {
panic(err)
}
Publish a message to the room:
if err := room.Publish("Hello, world!"); err != nil {
fmt.Printf("Error publishing message: %s\n", err)
}
Listen for incoming messages in a separate goroutine:
go func() {
for msg := range room.Messages {
fmt.Printf("[%s] %s: %s\n", roomName, msg.SenderNick, msg.Message)
}
}()
Here's a complete example of using the p2p
package in a chat application:
package main
import (
"bufio"
"context"
"flag"
"fmt"
"os"
"strings"
"p2p-sdk/p2p"
)
func main() {
nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty")
roomFlag := flag.String("room", "example-room", "name of chat room to join")
flag.Parse()
ctx := context.Background()
p2pInstance, err := p2p.NewP2P(ctx)
if err != nil {
panic(err)
}
nick := *nickFlag
if len(nick) == 0 {
nick = p2p.DefaultNick(p2pInstance.Host.ID())
}
roomName := *roomFlag
room, err := p2pInstance.JoinRoom(ctx, roomName, nick)
if err != nil {
panic(err)
}
go func() {
for msg := range room.Messages {
fmt.Printf("[%s] %s: %s\n", roomName, msg.SenderNick, msg.Message)
}
}()
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if strings.TrimSpace(text) == "" {
continue
}
if text == "/quit" {
break
}
if err := room.Publish(text); err != nil {
fmt.Printf("Error publishing message: %s\n", err)
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("Error reading from stdin: %s\n", err)
}
select {}
}
The package is organized into the following files:
p2p.go
: Main initialization and room management.pubsub.go
: Pubsub messaging functions.mdns.go
: mDNS peer discovery functions.utils.go
: Utility functions.
NewP2P(ctx context.Context) (*P2P, error)
Initializes a new P2P instance with a libp2p host and pubsub system.
(p2p *P2P) JoinRoom(ctx context.Context, roomName, nick string) (*EventRoom, error)
Joins a pubsub room with the given name and nickname.
(room *EventRoom) Publish(message string) error
Publishes a message to the pubsub topic.
(room *EventRoom) ListPeers() []peer.ID
Lists peers currently in the pubsub topic.
SetupDiscovery(h host.Host) error
Sets up mDNS peer discovery for the given host.
PrintErr(m string, args ...interface{})
DefaultNick(p peer.ID) string
ShortID(p peer.ID) string
This package is open-source and available under the MIT License.
Contributions are welcome! Please open an issue or submit a pull request.
This README provides a comprehensive overview of the p2p
package, its installation, usage, and directory structure. Feel free to adjust it based on your specific needs and project details.