8 log "github.com/sirupsen/logrus"
10 "github.com/vapor/event"
14 logModule = "p2p/mdns"
15 registerServiceCycle = 10 * time.Minute
16 registerServiceDelay = 2 * time.Second
19 // LANPeerEvent represent LAN peer ip and port.
20 type LANPeerEvent struct {
25 // mDNSProtocol mdns protocol interface.
26 type mDNSProtocol interface {
27 registerService(port int) error
28 registerResolver(event chan LANPeerEvent) error
33 // LANDiscover responsible for finding the related services registered LAN nodes.
34 type LANDiscover struct {
37 servicePort int //service port
38 entries chan LANPeerEvent
39 eventDispatcher *event.Dispatcher
43 // NewLANDiscover create a new LAN node discover.
44 func NewLANDiscover(protocol mDNSProtocol, port int) *LANDiscover {
48 entries: make(chan LANPeerEvent, 1024),
49 eventDispatcher: event.NewDispatcher(),
50 quite: make(chan struct{}),
53 go ld.registerServiceRoutine()
54 go ld.getLANPeerLoop()
58 // Stop stop LAN discover.
59 func (ld *LANDiscover) Stop() {
61 ld.protocol.stopResolver()
62 ld.protocol.stopService()
63 ld.eventDispatcher.Stop()
66 // Subscribe used to subscribe for LANPeerEvent.
67 func (ld *LANDiscover) Subscribe() (*event.Subscription, error) {
68 //subscribe LANPeerEvent.
69 sub, err := ld.eventDispatcher.Subscribe(LANPeerEvent{})
74 //need to register the parser once.
75 if atomic.CompareAndSwapUint32(&ld.resolving, 0, 1) {
76 if err = ld.protocol.registerResolver(ld.entries); err != nil {
84 // register service routine, will be re-registered periodically
85 // for the stability of node discovery.
86 func (ld *LANDiscover) registerServiceRoutine() {
87 time.Sleep(registerServiceDelay)
88 if err := ld.protocol.registerService(ld.servicePort); err != nil {
89 log.WithFields(log.Fields{"module": logModule, "err": err}).Error("mdns service register error")
93 ticker := time.NewTicker(registerServiceCycle)
98 ld.protocol.stopService()
99 if err := ld.protocol.registerService(ld.servicePort); err != nil {
100 log.WithFields(log.Fields{"module": logModule, "err": err}).Error("mdns service register error")
109 // obtain the lan peer event from the specific protocol
110 // and distribute it to the subscriber.
111 func (ld *LANDiscover) getLANPeerLoop() {
114 case entry := <-ld.entries:
115 if err := ld.eventDispatcher.Post(entry); err != nil {
116 log.WithFields(log.Fields{"module": logModule, "err": err}).Error("event dispatch error")