-
Notifications
You must be signed in to change notification settings - Fork 3
/
server.go
81 lines (70 loc) · 1.95 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package connqc
import (
"errors"
"io"
"net"
"time"
"github.com/hamba/logger/v2"
lctx "github.com/hamba/logger/v2/ctx"
)
// Server handles connections from clients.
type Server struct {
bufSize int
readTimeout time.Duration
writeTimeout time.Duration
log *logger.Logger
}
// NewServer returns a server.
func NewServer(bufSize int, readTimeout, writeTimeout time.Duration, log *logger.Logger) *Server {
return &Server{
bufSize: bufSize,
readTimeout: readTimeout,
writeTimeout: writeTimeout,
log: log,
}
}
// Serve handles a connection from a client.
//
// The handler provides an identical response to every message it receives.
// The caller who initiated the connection is responsible for ensuring its closure.
func (s *Server) Serve(conn net.PacketConn) { //nolint:cyclop // Simplify readability.
buf := make([]byte, s.bufSize)
for {
log := s.log
_ = conn.SetReadDeadline(time.Now().Add(s.readTimeout))
n, addr, err := conn.ReadFrom(buf)
if addr != nil {
log = log.With(lctx.Str("protocol", addr.Network()), lctx.Str("addr", addr.String()))
}
if err != nil {
var netErr net.Error
switch {
case errors.Is(err, io.EOF):
return
case errors.Is(err, net.ErrClosed):
return
case errors.As(err, &netErr) && netErr.Timeout():
log.Error("Reading from connection timed out", lctx.Err(err))
continue
default:
s.log.Error("Could not read request", lctx.Err(err))
continue
}
}
log.Debug("Message received", lctx.Str("data", string(buf[:n])))
_ = conn.SetWriteDeadline(time.Now().Add(s.writeTimeout))
wn, err := conn.WriteTo(buf[:n], addr)
switch {
case err != nil && errors.Is(err, net.ErrClosed):
return
case err != nil:
log.Error("Could not write response", lctx.Err(err))
continue
}
if wn != n {
log.Error("Unexpected write length", lctx.Int("expected", n), lctx.Int("actual", wn))
continue
}
log.Debug("Message sent", lctx.Str("data", string(buf[:n])))
}
}