Skip to content

Commit 46d9ffa

Browse files
committed
refactor: peer registration and discovery
Implemented at pkg/peer package and it's now only one server that handles the server registration and client discovery
1 parent f4f7367 commit 46d9ffa

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

pkg/peer/peer.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Peer package is containes all the componets related with the network peers.
2+
//
3+
// Components:
4+
//
5+
// - peerserver.go -> Registration and peer discovery
6+
//
7+
package peer
8+
9+
import (
10+
"net"
11+
"strings"
12+
)
13+
14+
const (
15+
serviceName = `_catchmyfile._tcp`
16+
serviceDomain = `local.`
17+
)
18+
19+
// Peer defines a network peer that can send and receive files.
20+
type Peer struct {
21+
// Name is the peers name.
22+
Name string
23+
// Address - os the net.IP address of the peer.
24+
Address net.IP
25+
// Port is the network port where the peer will receive connections.
26+
Port int
27+
}
28+
29+
// newPeer will create a new instance of the struct Peer and return it.
30+
//
31+
// It receives a string with the name of the peer, the ip address and
32+
// the port where the peer will receive connections for file transfers.
33+
func newPeer(name string, address net.IP, port int) Peer {
34+
return Peer{
35+
Name: strings.Replace(name, ".local.", "", 1),
36+
Address: address,
37+
Port: port,
38+
}
39+
}

pkg/peer/peerserver.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package peer
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/grandcat/zeroconf"
8+
)
9+
10+
// Server defines the server that registers the peer and discover other peers.
11+
// It wrappes the logic for zeroconf.
12+
//
13+
// Done is a channel that is closed when the Server finish the execution.
14+
type Server struct {
15+
Done chan interface{}
16+
name string
17+
port int
18+
}
19+
20+
// NewServer will create a new peer discover server.
21+
//
22+
// The port is the port number used for the TCP connections
23+
// from where the files will be transfered.
24+
func NewServer(name string, port int) *Server {
25+
return &Server{
26+
name: name,
27+
port: port,
28+
Done: make(chan interface{}),
29+
}
30+
}
31+
32+
// Run will start the Server that will register the peer and start looking for
33+
// peers on the local network with zeroconf.
34+
//
35+
// Arguments:
36+
//
37+
// - ctx is a context with cancel, what will be used to terminate the server.
38+
//
39+
// - peers is a channel of Peer that will stream each peer discovered on the
40+
// network.
41+
//
42+
// Errors:
43+
//
44+
// - on registering the service
45+
//
46+
// - on start listening
47+
//
48+
// - on discover
49+
func (s *Server) Run(ctx context.Context, peers chan Peer) error {
50+
instance := fmt.Sprintf("catch-%s", s.name)
51+
sv, err := zeroconf.Register(instance, serviceName, serviceDomain, s.port, nil, nil)
52+
if err != nil {
53+
return fmt.Errorf("peer server fail to register: %v", err)
54+
}
55+
56+
resolver, err := zeroconf.NewResolver(zeroconf.SelectIPTraffic(zeroconf.IPv4))
57+
if err != nil {
58+
return fmt.Errorf("peer server fail to start listening: %v", err)
59+
}
60+
61+
entries := make(chan *zeroconf.ServiceEntry)
62+
err = resolver.Browse(ctx, serviceName, serviceDomain, entries)
63+
if err != nil {
64+
return fmt.Errorf("peer server fail to discover: %v", err)
65+
}
66+
67+
go func(results <-chan *zeroconf.ServiceEntry) {
68+
for entry := range results {
69+
peers <- newPeer(entry.HostName, entry.AddrIPv4[0], entry.Port)
70+
}
71+
sv.Shutdown()
72+
close(s.Done)
73+
// entries is already closed by the context cancelation
74+
}(entries)
75+
76+
return nil
77+
}

0 commit comments

Comments
 (0)