individually tick heartbeat for each client

This commit is contained in:
Reese Norris
2024-10-22 12:41:35 -07:00
parent c0cc3d218e
commit a683c24300
2 changed files with 12 additions and 29 deletions

View File

@@ -4,15 +4,12 @@ import (
"context"
"errors"
"github.com/renorris/openfsd/client"
"github.com/renorris/openfsd/postoffice"
"github.com/renorris/openfsd/protocol"
"github.com/renorris/openfsd/servercontext"
"log"
"net"
"os"
"slices"
"sync"
"time"
)
type FSDService struct{}
@@ -50,10 +47,6 @@ func (s *FSDService) boot(ctx context.Context, listener *net.TCPListener) error
// Track each client connection in a wait group
waitGroup := sync.WaitGroup{}
// Start heartbeat worker
waitGroup.Add(1)
go s.heartbeatWorker(ctx, &waitGroup)
for {
select {
// Handle incoming connections
@@ -120,25 +113,3 @@ func (s *FSDService) resolveAndListen() (listener *net.TCPListener, err error) {
return listener, nil
}
func (s *FSDService) heartbeatWorker(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
heartbeatPacket := "#DLSERVER:*:0:0" + protocol.PacketDelimiter
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
// Send server heartbeat every 30 seconds
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
servercontext.PostOffice().ForEachRegistered(func(name string, address postoffice.Address) bool {
address.SendMail(heartbeatPacket)
return true
})
}
}
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/renorris/openfsd/protocol"
"github.com/renorris/openfsd/servercontext"
"log"
"time"
)
// EventLoop runs the main event loop for a logged in client
@@ -18,6 +19,11 @@ func (c *FSDClient) EventLoop() error {
log.Printf("client_disconnected total_clients=%d %s", servercontext.PostOffice().NumRegistered()-1, infoStr)
}()
// Set up heartbeat ticker
heartbeatPacket := "#DLSERVER:*:0:0" + protocol.PacketDelimiter
heartbeatTicker := time.NewTicker(30 * time.Second)
defer heartbeatTicker.Stop()
// Post-login FSD client event loop
for {
select {
@@ -43,6 +49,12 @@ func (c *FSDClient) EventLoop() error {
// Handle incoming kill signals
case killPacket := <-c.kill:
return c.connection.WritePacketImmediately(killPacket)
// Listen for heartbeat ticker
case <-heartbeatTicker.C:
if err := c.connection.WritePacket(heartbeatPacket); err != nil {
return err
}
}
}
}