diff --git a/go.mod b/go.mod index 7566fa5..5a1179c 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/RoboCup-SSL/ssl-status-board go 1.21 -require github.com/gorilla/websocket v1.5.3 - -require golang.org/x/net v0.34.0 // indirect +require ( + github.com/RoboCup-SSL/ssl-go-tools v1.8.1 + github.com/gorilla/websocket v1.5.3 +) diff --git a/go.sum b/go.sum index 0f6db1b..e34c60c 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,4 @@ -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/RoboCup-SSL/ssl-go-tools v1.8.1 h1:6EAIeJdgr2BO1lfQNrt1vNFFKiKScqjd1HrZsCZ07rg= +github.com/RoboCup-SSL/ssl-go-tools v1.8.1/go.mod h1:FuTw472klW5wAMg09gxQqPCzu6ygxOdMA8D22fDOUfM= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= diff --git a/pkg/board/board.go b/pkg/board/board.go index 599f254..c777656 100644 --- a/pkg/board/board.go +++ b/pkg/board/board.go @@ -2,9 +2,10 @@ package board import ( "fmt" - "github.com/RoboCup-SSL/ssl-status-board/pkg/sslnet" + "github.com/RoboCup-SSL/ssl-go-tools/pkg/sslnet" "github.com/gorilla/websocket" "log" + "net" "net/http" "sync" "time" @@ -23,13 +24,14 @@ type Board struct { func NewBoard(cfg RefereeConfig) (b *Board) { b = new(Board) b.cfg = cfg - b.MulticastServer = sslnet.NewMulticastServer(b.handlingMessage) + b.MulticastServer = sslnet.NewMulticastServer(b.cfg.MulticastAddress) + b.MulticastServer.Consumer = b.handlingMessage return } // Start listening for messages func (b *Board) Start() { - b.MulticastServer.Start(b.cfg.MulticastAddress) + b.MulticastServer.Start() } // Stop listening for messages @@ -37,7 +39,7 @@ func (b *Board) Stop() { b.MulticastServer.Stop() } -func (b *Board) handlingMessage(data []byte) { +func (b *Board) handlingMessage(data []byte, _ *net.UDPAddr) { b.mutex.Lock() defer b.mutex.Unlock() b.refereeData = data diff --git a/pkg/sslnet/multicast_receiver.go b/pkg/sslnet/multicast_receiver.go deleted file mode 100644 index 2e5ad26..0000000 --- a/pkg/sslnet/multicast_receiver.go +++ /dev/null @@ -1,139 +0,0 @@ -package sslnet - -import ( - "log" - "net" - "sync" - "time" -) - -const maxDatagramSize = 8192 - -type MulticastServer struct { - connection *net.UDPConn - running bool - consumer func([]byte) - mutex sync.Mutex - SkipInterfaces []string - Verbose bool -} - -func NewMulticastServer(consumer func([]byte)) (r *MulticastServer) { - r = new(MulticastServer) - r.consumer = consumer - return -} - -func (r *MulticastServer) Start(multicastAddress string) { - r.running = true - go r.receive(multicastAddress) -} - -func (r *MulticastServer) Stop() { - r.mutex.Lock() - defer r.mutex.Unlock() - r.running = false - if err := r.connection.Close(); err != nil { - log.Println("Could not close connection: ", err) - } -} - -func (r *MulticastServer) receive(multicastAddress string) { - log.Printf("Receiving on %v", multicastAddress) - var currentIfiIdx = 0 - for r.isRunning() { - ifis := r.interfaces() - currentIfiIdx = currentIfiIdx % len(ifis) - ifi := ifis[currentIfiIdx] - r.receiveOnInterface(multicastAddress, ifi) - currentIfiIdx++ - if currentIfiIdx >= len(ifis) { - // cycled though all interfaces once, make a short break to avoid producing endless log messages - time.Sleep(1 * time.Second) - } - } -} - -func (r *MulticastServer) isRunning() bool { - r.mutex.Lock() - defer r.mutex.Unlock() - return r.running -} - -func (r *MulticastServer) interfaces() (interfaces []net.Interface) { - interfaces = []net.Interface{} - ifis, err := net.Interfaces() - if err != nil { - log.Println("Could not get available interfaces: ", err) - } - for _, ifi := range ifis { - if ifi.Flags&net.FlagMulticast == 0 || // No multicast support - r.skipInterface(ifi.Name) { - continue - } - interfaces = append(interfaces, ifi) - } - return -} - -func (r *MulticastServer) skipInterface(ifiName string) bool { - for _, skipIfi := range r.SkipInterfaces { - if skipIfi == ifiName { - return true - } - } - return false -} - -func (r *MulticastServer) receiveOnInterface(multicastAddress string, ifi net.Interface) { - addr, err := net.ResolveUDPAddr("udp", multicastAddress) - if err != nil { - log.Printf("Could resolve multicast address %v: %v", multicastAddress, err) - return - } - - r.connection, err = net.ListenMulticastUDP("udp", &ifi, addr) - if err != nil { - log.Printf("Could not listen at %v: %v", multicastAddress, err) - return - } - - if err := r.connection.SetReadBuffer(maxDatagramSize); err != nil { - log.Println("Could not set read buffer: ", err) - } - - if r.Verbose { - log.Printf("Listening on %s (%s)", multicastAddress, ifi.Name) - } - - first := true - data := make([]byte, maxDatagramSize) - for { - if err := r.connection.SetDeadline(time.Now().Add(300 * time.Millisecond)); err != nil { - log.Println("Could not set deadline on connection: ", err) - } - n, _, err := r.connection.ReadFromUDP(data) - if err != nil { - if r.Verbose { - log.Println("ReadFromUDP failed:", err) - } - break - } - - if first { - log.Printf("Got first data packets from %s (%s)", multicastAddress, ifi.Name) - first = false - } - - r.consumer(data[:n]) - } - - if r.Verbose { - log.Printf("Stop listening on %s (%s)", multicastAddress, ifi.Name) - } - - if err := r.connection.Close(); err != nil { - log.Println("Could not close listener: ", err) - } - return -}