99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/usrpserv/config"
|
|
"log"
|
|
"net"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Clients struct {
|
|
sync.Mutex
|
|
Client map[string]Client
|
|
Sock *net.UDPConn
|
|
}
|
|
|
|
type Client struct {
|
|
Connected time.Time
|
|
Network net.UDPAddr
|
|
}
|
|
|
|
func New() Clients {
|
|
var clients Clients
|
|
clients.Mutex = sync.Mutex{}
|
|
clients.Client = make(map[string]Client, 8)
|
|
return clients
|
|
}
|
|
|
|
func (c *Clients) remove(name string) {
|
|
delete(c.Client, name)
|
|
}
|
|
|
|
func (c *Clients) Add(name string, addr *net.UDPAddr) {
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
if client, ok := c.Client[name]; ok {
|
|
if time.Since(client.Connected).Minutes() < 1 {
|
|
return
|
|
}
|
|
client.Connected = time.Now()
|
|
log.Printf("client %s has updated", name)
|
|
return
|
|
}
|
|
log.Println("adding client:", name)
|
|
c.Client[name] = Client{
|
|
Connected: time.Now(),
|
|
Network: *addr,
|
|
}
|
|
}
|
|
|
|
func (c *Clients) Run(config *config.Config) error {
|
|
if !config.Server.Enable {
|
|
log.Println("Server not enabled")
|
|
return nil
|
|
}
|
|
var err error
|
|
c.Sock, err = net.ListenUDP("udp4", &net.UDPAddr{IP: net.ParseIP(config.Server.UDP.IP), Port: config.Server.UDP.Port})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buffer := make([]byte, 32)
|
|
go func() {
|
|
for {
|
|
n, addr, err := c.Sock.ReadFromUDP(buffer)
|
|
if err != nil {
|
|
log.Printf("Error reading from %v\n", err)
|
|
}
|
|
if n < 1 {
|
|
continue
|
|
}
|
|
c.Add(addr.String(), addr)
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
func (c *Clients) SendData(data []byte, expire int64) {
|
|
if len(data) == 0 {
|
|
return
|
|
}
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
for key, client := range c.Client {
|
|
_, err := c.Sock.WriteToUDP(data, &client.Network)
|
|
if err != nil {
|
|
log.Println(err)
|
|
c.remove(key)
|
|
continue
|
|
}
|
|
if time.Now().Sub(client.Connected) > time.Duration(expire)*time.Minute {
|
|
log.Println("removing client:", key)
|
|
c.remove(key)
|
|
continue
|
|
}
|
|
fmt.Println("Sending to client:", key)
|
|
}
|
|
}
|