70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
package wshub
|
|
|
|
import (
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"marte2/common/udpsprotocol"
|
|
)
|
|
|
|
// TestUDPClientSendsPeriodicKeepAliveAcks verifies that a unicast UDPClient
|
|
// re-sends ACK datagrams from the SAME socket at keepAliveInterval. The
|
|
// UDPSServer refreshes a unicast client's last-seen only on client->server
|
|
// traffic; without this keepalive it evicts the client after ClientTimeout
|
|
// (default 30 s) and the stream dies.
|
|
func TestUDPClientSendsPeriodicKeepAliveAcks(t *testing.T) {
|
|
srv, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.ParseIP("127.0.0.1")})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer srv.Close()
|
|
|
|
c := NewUDPClient(srv.LocalAddr().String(), "ka1", NewHub(), "", 0)
|
|
c.keepAliveInterval = 150 * time.Millisecond
|
|
go c.Run()
|
|
defer c.Stop()
|
|
|
|
buf := make([]byte, 512)
|
|
|
|
// 1) CONNECT from the client's ephemeral socket.
|
|
srv.SetReadDeadline(time.Now().Add(3 * time.Second))
|
|
n, clientAddr, err := srv.ReadFromUDP(buf)
|
|
if err != nil {
|
|
t.Fatalf("expected CONNECT: %v", err)
|
|
}
|
|
hdr, err := udpsprotocol.ParseHeader(buf[:n])
|
|
if err != nil {
|
|
t.Fatalf("parse CONNECT: %v", err)
|
|
}
|
|
if hdr.Type != udpsprotocol.PktConnect {
|
|
t.Fatalf("first packet type = %d, want CONNECT (%d)", hdr.Type, udpsprotocol.PktConnect)
|
|
}
|
|
|
|
// 2) Collect ACKs for ~1 s: must be periodic and from the SAME socket
|
|
// (a new ephemeral socket would be registered as a new client).
|
|
deadline := time.Now().Add(time.Second)
|
|
acks := 0
|
|
for time.Now().Before(deadline) {
|
|
srv.SetReadDeadline(deadline)
|
|
n, addr, err := srv.ReadFromUDP(buf)
|
|
if err != nil {
|
|
break
|
|
}
|
|
hdr, err := udpsprotocol.ParseHeader(buf[:n])
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if hdr.Type != udpsprotocol.PktACK {
|
|
t.Fatalf("unexpected packet type %d from %s", hdr.Type, addr)
|
|
}
|
|
if addr.String() != clientAddr.String() {
|
|
t.Fatalf("ACK from %s, want same socket as CONNECT (%s)", addr, clientAddr)
|
|
}
|
|
acks++
|
|
}
|
|
if acks < 3 {
|
|
t.Fatalf("expected >= 3 keepalive ACKs in 1 s, got %d", acks)
|
|
}
|
|
}
|