package broadcast
|
|
import (
|
"fmt"
|
"github.com/gogf/greuse"
|
"strconv"
|
"strings"
|
"sync"
|
"time"
|
)
|
|
var (
|
port = 31995
|
lport = 31996
|
|
lock sync.Mutex //同一时刻只能有一个线程在执行搜索
|
)
|
|
|
//广播收集其他节点信息
|
func BroadCast() ([]string, error) {
|
lock.Lock()
|
defer lock.Unlock()
|
|
retCh := make(chan []string)
|
go startRecv(retCh)
|
|
conn, err := greuse.Dial("udp", "0.0.0.0:"+strconv.Itoa(lport), "255.255.255.255:"+strconv.Itoa(port))
|
|
if err != nil {
|
fmt.Println("err:", err)
|
} else {
|
defer conn.Close()
|
|
n,err := conn.Write([]byte("who are you?"))
|
if err != nil || n == 0 {
|
fmt.Println("conn.Write err:", err, " n:", n)
|
}
|
}
|
|
nodes := <-retCh
|
|
return nodes, nil
|
}
|
|
func startRecv(rCh chan []string) {
|
conn, err := greuse.ListenPacket("udp", "0.0.0.0:"+strconv.Itoa(lport))
|
|
if err != nil {
|
fmt.Println("startRecv ListenPacket err:", err)
|
rCh <- []string{}
|
return
|
}
|
//10秒钟之内收到的返回,即认为是在线的
|
conn.SetReadDeadline(time.Now().Add(time.Second * 1))
|
ch := time.After(time.Second * 4)
|
var nodes []string
|
Loop:
|
for {
|
select {
|
case <-ch:
|
fmt.Println("<-ch")
|
break Loop
|
default:
|
ret := make([]byte, 1024)
|
n, from, e := conn.ReadFrom(ret)
|
if e == nil && n >0 {
|
arr := strings.Split(from.String(), ":")
|
if len(arr) == 2 {
|
nodes = append(nodes, arr[0])
|
}
|
fmt.Println("read message from udp:", string(ret), " from:", from)
|
} else {
|
time.Sleep(time.Millisecond * 100)
|
}
|
}
|
}
|
rCh <- nodes
|
}
|