-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.go
More file actions
114 lines (89 loc) · 2.29 KB
/
server.go
File metadata and controls
114 lines (89 loc) · 2.29 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package sockit
import (
"crypto/tls"
"errors"
"fmt"
"net"
"sync/atomic"
)
// ConnManager manage accepted connections
type ConnManager interface {
// StoreConn store connections, and verify the connection is acceptable.
// if acceptable, a Session will be returned.
StoreConn(c Conn) (*Session, error)
// FindSession find the Session specified by id
FindSession(id int64) (*Session, bool)
// RemoveSession find the Session and remove the Session from the pool.
// The Session will be closed before removed.
RemoveSession(id int64) error
// RangeSession accepted a process function.
// Every stored Session will be passed to function.
RangeSession(fn func(session *Session))
// Close close all sessions and release all resources.
Close() error
}
type Server struct {
listener net.Listener
Codec Codec
Manager ConnManager
closed int32
}
// NewServer create a new tcp server.
func NewServer(mgr ConnManager, codec Codec) *Server {
return &Server{
Codec: codec,
Manager: mgr,
}
}
var ErrorServerClosed = fmt.Errorf("server closed")
// ListenAndServe is like http.ListenAndServe, it listens given address
// and accept new connections to the server, then pass the connection to ConnManager.
func (s *Server) ListenAndServe(addr string) error {
listener, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return s.Serve(listener)
}
func (s *Server) ListenAndServeTLS(addr string, certFile string, keyFile string) error {
l, err := net.Listen("tcp", addr)
if err != nil {
return err
}
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return err
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
}
listener := tls.NewListener(l, config)
return s.Serve(listener)
}
func (s *Server) Serve(listener net.Listener) error {
s.listener = listener
for atomic.LoadInt32(&s.closed) != 1 {
c, err := listener.Accept()
if err != nil {
if errors.Is(err, net.ErrClosed) {
return nil
}
return err
}
s.Manager.StoreConn(newConn(c, s.Codec))
}
return nil
}
// Close the listener and ConnManager.
func (s *Server) Close() error {
if !atomic.CompareAndSwapInt32(&s.closed, 0, 1) {
return nil
}
if err := s.listener.Close(); err != nil {
return err
}
if err := s.Manager.Close(); err != nil {
return err
}
return nil
}