From e9ad790d04ef06cf2214505817a03ab298e7582d Mon Sep 17 00:00:00 2001 From: Alex Mylonas Date: Sun, 5 Oct 2025 20:58:38 +0300 Subject: [PATCH 1/2] feat: handle room flag --- go-peer/chatroom.go | 3 ++- go-peer/main.go | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/go-peer/chatroom.go b/go-peer/chatroom.go index f5fcd6a6..b3d2a31d 100644 --- a/go-peer/chatroom.go +++ b/go-peer/chatroom.go @@ -52,7 +52,7 @@ type ChatMessage struct { // JoinChatRoom tries to subscribe to the PubSub topic for the room name, returning // a ChatRoom on success. -func JoinChatRoom(ctx context.Context, h host.Host, ps *pubsub.PubSub, nickname string) (*ChatRoom, error) { +func JoinChatRoom(ctx context.Context, h host.Host, ps *pubsub.PubSub, nickname string, roomName string) (*ChatRoom, error) { // join the pubsub chatTopic chatTopic, err := ps.Join(ChatTopic) if err != nil { @@ -100,6 +100,7 @@ func JoinChatRoom(ctx context.Context, h host.Host, ps *pubsub.PubSub, nickname peerDiscoveryTopic: peerDiscoveryTopic, peerDiscoverySub: peerDiscoverySub, nick: nickname, + roomName: roomName, Messages: make(chan *ChatMessage, ChatRoomBufSize), SysMessages: make(chan *ChatMessage, ChatRoomBufSize), } diff --git a/go-peer/main.go b/go-peer/main.go index 5ec66ab5..26e6b20c 100644 --- a/go-peer/main.go +++ b/go-peer/main.go @@ -108,6 +108,7 @@ func main() { // parse some flags to set our nickname and the room to join nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty") idPath := flag.String("identity", "identity.key", "path to the private key (PeerID) file") +roomFlag := flag.String("room", "", "The room to join") headless := flag.Bool("headless", false, "run without chat UI") var addrsToConnectTo stringSlice @@ -210,8 +211,13 @@ func main() { nick = defaultNick(h.ID()) } + roomName := *roomFlag + if len(roomName) == 0 { + roomName = defaultRoom() + } + // join the chat room - cr, err := JoinChatRoom(ctx, h, ps, nick) + cr, err := JoinChatRoom(ctx, h, ps, nick, roomName) if err != nil { panic(err) } @@ -315,6 +321,10 @@ func defaultNick(p peer.ID) string { return fmt.Sprintf("%s-%s", os.Getenv("USER"), shortID(p)) } +func defaultRoom() string { + return "default" +} + // shortID returns the last 8 chars of a base58-encoded peer id. func shortID(p peer.ID) string { str := p.String() From 5e22f8973e99631ec8191b79d1e69b6e7518fc4b Mon Sep 17 00:00:00 2001 From: Alex Mylonas Date: Sun, 5 Oct 2025 21:27:26 +0300 Subject: [PATCH 2/2] feat: roomName acts like a service name for mDNS discovery --- go-peer/main.go | 40 +++++++++++++++++++--------------------- go-peer/ui.go | 2 +- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/go-peer/main.go b/go-peer/main.go index 26e6b20c..d19913e1 100644 --- a/go-peer/main.go +++ b/go-peer/main.go @@ -34,9 +34,6 @@ import ( // DiscoveryInterval is how often we re-publish our mDNS records. const DiscoveryInterval = time.Hour -// DiscoveryServiceTag is used in our mDNS advertisements to discover other chat peers. -const DiscoveryServiceTag = "universal-connectivity" - var SysMsgChan chan *ChatMessage var logger = log.Logger("app") @@ -64,10 +61,10 @@ func NewDHT(ctx context.Context, host host.Host, bootstrapPeers []multiaddr.Mult // Borrowed from https://medium.com/rahasak/libp2p-pubsub-peer-discovery-with-kademlia-dht-c8b131550ac7 // Only used by Go peer to find each other. // TODO: since this isn't implemented on the Rust or the JS side, can probably be removed -func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT) { +func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, tag string) { routingDiscovery := routing.NewRoutingDiscovery(dht) - discovery.Advertise(ctx, routingDiscovery, DiscoveryServiceTag) + discovery.Advertise(ctx, routingDiscovery, tag) ticker := time.NewTicker(time.Second * 10) defer ticker.Stop() @@ -78,7 +75,7 @@ func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT) { return case <-ticker.C: - peers, err := discovery.FindPeers(ctx, routingDiscovery, DiscoveryServiceTag) + peers, err := discovery.FindPeers(ctx, routingDiscovery, tag) if err != nil { panic(err) } @@ -108,7 +105,7 @@ func main() { // parse some flags to set our nickname and the room to join nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty") idPath := flag.String("identity", "identity.key", "path to the private key (PeerID) file") -roomFlag := flag.String("room", "", "The room to join") + roomFlag := flag.String("room", "", "The room to join") headless := flag.Bool("headless", false, "run without chat UI") var addrsToConnectTo stringSlice @@ -154,16 +151,16 @@ roomFlag := flag.String("room", "", "The room to join") libp2p.Identity(privk), libp2p.NATPortMap(), libp2p.ListenAddrStrings( - "/ip4/0.0.0.0/tcp/9095", - "/ip4/0.0.0.0/udp/9095/quic-v1", - "/ip4/0.0.0.0/udp/9095/quic-v1/webtransport", - "/ip4/0.0.0.0/udp/9095/webrtc-direct", - "/ip6/::/tcp/9095", - "/ip6/::/udp/9095/quic-v1", - "/ip6/::/udp/9095/quic-v1/webtransport", - "/ip6/::/udp/9095/webrtc-direct", - fmt.Sprintf("/ip4/0.0.0.0/tcp/9095/tls/sni/*.%s/ws", p2pforge.DefaultForgeDomain), - fmt.Sprintf("/ip6/::/tcp/9095/tls/sni/*.%s/ws", p2pforge.DefaultForgeDomain), + "/ip4/0.0.0.0/tcp/0", + "/ip4/0.0.0.0/udp/0/quic-v1", + "/ip4/0.0.0.0/udp/0/quic-v1/webtransport", + "/ip4/0.0.0.0/udp/0/webrtc-direct", + "/ip6/::/tcp/0", + "/ip6/::/udp/0/quic-v1", + "/ip6/::/udp/0/quic-v1/webtransport", + "/ip6/::/udp/0/webrtc-direct", + fmt.Sprintf("/ip4/0.0.0.0/tcp/0/tls/sni/*.%s/ws", p2pforge.DefaultForgeDomain), + fmt.Sprintf("/ip6/::/tcp/0/tls/sni/*.%s/ws", p2pforge.DefaultForgeDomain), ), libp2p.ResourceManager(getResourceManager()), libp2p.Transport(webtransport.New), @@ -231,11 +228,12 @@ roomFlag := flag.String("room", "", "The room to join") panic(err) } + tag := roomName // setup peer discovery - go Discover(ctx, h, dht) + go Discover(ctx, h, dht, tag) // setup local mDNS discovery - if err := setupDiscovery(h); err != nil { + if err := setupDiscovery(h, tag); err != nil { panic(err) } @@ -349,9 +347,9 @@ func (n *discoveryNotifee) HandlePeerFound(pi peer.AddrInfo) { // setupDiscovery creates an mDNS discovery service and attaches it to the libp2p Host. // This lets us automatically discover peers on the same LAN and connect to them. -func setupDiscovery(h host.Host) error { +func setupDiscovery(h host.Host, serviceName string) error { // setup mDNS discovery to find local peers - s := mdns.NewMdnsService(h, DiscoveryServiceTag, &discoveryNotifee{h: h}) + s := mdns.NewMdnsService(h, serviceName, &discoveryNotifee{h: h}) return s.Start() } diff --git a/go-peer/ui.go b/go-peer/ui.go index 13d4d040..37bae421 100644 --- a/go-peer/ui.go +++ b/go-peer/ui.go @@ -34,7 +34,7 @@ func NewChatUI(cr *ChatRoom) *ChatUI { msgBox := tview.NewTextView() msgBox.SetDynamicColors(true) msgBox.SetBorder(true) - msgBox.SetTitle(fmt.Sprintf("Room: %s", cr.roomName)) + msgBox.SetTitle(fmt.Sprintf("Room: %s ", cr.roomName)) // text views are io.Writers, but they don't automatically refresh. // this sets a change handler to force the app to redraw when we get