UPnP/SSDP client: allow clean shutdowns

The SSDP library will log a warning on shutdown, as it doesn't expect the
UDP socket to be closed. Copy the hack on the Server implementation, which
avoids this warning getting logged, to the Client.
This commit is contained in:
Sybren A. Stüvel 2022-03-08 13:53:56 +01:00
parent d0b677ffe3
commit 13a74e61d4

View File

@ -35,20 +35,22 @@ import (
type Client struct {
ssdp *gossdp.ClientSsdp
log *zerolog.Logger
wrappedLog *ssdpLogger
mutex *sync.Mutex
urls []string
}
func NewClient(logger zerolog.Logger) (*Client, error) {
wrap := wrappedLogger(&logger)
client := Client{
log: &logger,
wrappedLog: wrap,
mutex: new(sync.Mutex),
urls: make([]string, 0),
}
wrap := wrappedLogger(&logger)
ssdp, err := gossdp.NewSsdpClientWithLogger(&client, wrap)
if err != nil {
return nil, fmt.Errorf("create UPnP/SSDP client: %w", err)
@ -59,7 +61,7 @@ func NewClient(logger zerolog.Logger) (*Client, error) {
}
func (c *Client) Run(ctx context.Context) ([]string, error) {
defer c.ssdp.Stop()
defer c.stopCleanly()
log.Debug().Msg("waiting for UPnP/SSDP answer")
go c.ssdp.Start()
@ -125,3 +127,18 @@ func (c *Client) receivedURLs() []string {
copy(urls, c.urls)
return urls
}
// stopCleanly tries to stop the SSDP client cleanly, without spurious logging.
func (c *Client) stopCleanly() {
c.log.Trace().Msg("UPnP/SSDP client stopping")
// Sneakily disable warnings when shutting down, otherwise the read operation
// from the UDP socket will cause a warning.
tempLog := c.log.Level(zerolog.ErrorLevel)
c.wrappedLog.zlog = &tempLog
c.ssdp.Stop()
c.wrappedLog.zlog = c.log
c.log.Debug().Msg("UPnP/SSDP client stopped")
}