github.com/searKing/golang/go@v1.2.117/net/tcp/server.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tcp 6 7 import ( 8 "context" 9 "errors" 10 "io" 11 "log" 12 "net" 13 "sync" 14 "sync/atomic" 15 "time" 16 17 slices_ "github.com/searKing/golang/go/exp/slices" 18 time_ "github.com/searKing/golang/go/time" 19 ) 20 21 type Handler interface { 22 OnOpenHandler 23 OnMsgReadHandler 24 OnMsgHandleHandler 25 OnCloseHandler 26 OnErrorHandler 27 } 28 29 func NewServerFunc( 30 onOpen OnOpenHandler, 31 onMsgRead OnMsgReadHandler, 32 onMsgHandle OnMsgHandleHandler, 33 onClose OnCloseHandler, 34 onError OnErrorHandler) *Server { 35 return &Server{ 36 onOpenHandler: slices_.FirstOrZero[OnOpenHandler](onOpen, NopOnOpenHandler), 37 onMsgReadHandler: slices_.FirstOrZero[OnMsgReadHandler](onMsgRead, NopOnMsgReadHandler), 38 onMsgHandleHandler: slices_.FirstOrZero[OnMsgHandleHandler](onMsgHandle, NopOnMsgHandleHandler), 39 onCloseHandler: slices_.FirstOrZero[OnCloseHandler](onClose, NopOnCloseHandler), 40 onErrorHandler: slices_.FirstOrZero[OnErrorHandler](onError, NopOnErrorHandler), 41 } 42 } 43 func NewServer(h Handler) *Server { 44 return NewServerFunc(h, h, h, h, h) 45 } 46 47 type Server struct { 48 Addr string // TCP address to listen on, ":tcp" if empty 49 onOpenHandler OnOpenHandler 50 onMsgReadHandler OnMsgReadHandler 51 onMsgHandleHandler OnMsgHandleHandler 52 onCloseHandler OnCloseHandler 53 onErrorHandler OnErrorHandler 54 55 ReadTimeout time.Duration 56 WriteTimeout time.Duration 57 IdleTimeout time.Duration 58 MaxBytes int 59 60 ErrorLog *log.Logger 61 62 mu sync.Mutex 63 listeners map[*net.Listener]struct{} 64 activeConn map[*conn]struct{} 65 doneChan chan struct{} 66 onShutdown []func() 67 68 // server state 69 inShutdown atomic.Bool 70 71 // ConnState specifies an optional callback function that is 72 // called when a client connection changes state. See the 73 // ConnState type and associated constants for details. 74 ConnState func(net.Conn, ConnState) 75 } 76 77 func (srv *Server) CheckError(w io.Writer, r io.Reader, err error) error { 78 if err == nil { 79 return nil 80 } 81 return srv.onErrorHandler.OnError(w, r, err) 82 } 83 84 func (srv *Server) ListenAndServe() error { 85 if srv.shuttingDown() { 86 return srv.CheckError(nil, nil, ErrServerClosed) 87 } 88 addr := srv.Addr 89 if addr == "" { 90 addr = ":tcp" 91 } 92 ln, err := net.Listen("tcp", addr) 93 if srv.CheckError(nil, nil, err) != nil { 94 return err 95 } 96 return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) 97 } 98 99 func (srv *Server) Serve(l net.Listener) error { 100 l = &onceCloseListener{Listener: l} 101 defer l.Close() 102 103 // how long to sleep on accept failure 104 var tempDelay = time_.NewExponentialBackOff( 105 time_.WithExponentialBackOffOptionInitialInterval(5*time.Millisecond), 106 time_.WithExponentialBackOffOptionMaxInterval(time.Second), 107 time_.WithExponentialBackOffOptionMaxElapsedDuration(-1), 108 time_.WithExponentialBackOffOptionMaxElapsedCount(-1)) 109 ctx := context.WithValue(context.Background(), ServerContextKey, srv) 110 for { 111 rw, e := l.Accept() 112 if e != nil { 113 // return if server is cancaled, means normally close 114 select { 115 case <-srv.getDoneChan(): 116 return ErrServerClosed 117 default: 118 } 119 // retry if it's recoverable 120 var ne net.Error 121 if errors.As(e, &ne) && ne.Temporary() { 122 delay, ok := tempDelay.NextBackOff() 123 if !ok { 124 srv.logf("http: Accept error: %v; retried canceled as time exceed(%v)", e, tempDelay.GetMaxElapsedDuration()) 125 // return if timeout 126 return srv.CheckError(nil, nil, e) 127 } 128 srv.logf("http: Accept error: %v; retrying in %v", e, delay) 129 time.Sleep(delay) 130 continue 131 } 132 // return otherwise 133 return srv.CheckError(nil, nil, e) 134 } 135 tempDelay.Reset() 136 137 // takeover this connect 138 c := srv.newConn(rw) 139 // Handle websocket On 140 err := srv.onOpenHandler.OnOpen(c.rwc) 141 if err = srv.CheckError(c.w, c.r, err); err != nil { 142 c.close() 143 return err 144 } 145 c.setState(c.rwc, StateNew) // before Serve can return 146 go c.serve(ctx) 147 } 148 } 149 150 func (srv *Server) trackConn(c *conn, add bool) { 151 srv.mu.Lock() 152 defer srv.mu.Unlock() 153 if srv.activeConn == nil { 154 srv.activeConn = make(map[*conn]struct{}) 155 } 156 if add { 157 srv.activeConn[c] = struct{}{} 158 } else { 159 delete(srv.activeConn, c) 160 } 161 } 162 163 // Create new connection from rwc. 164 func (srv *Server) newConn(rwc net.Conn) *conn { 165 c := &conn{ 166 server: srv, 167 rwc: rwc, 168 } 169 return c 170 } 171 172 func (srv *Server) logf(format string, args ...any) { 173 if srv.ErrorLog != nil { 174 srv.ErrorLog.Printf(format, args...) 175 } else { 176 log.Printf(format, args...) 177 } 178 } 179 180 func ListenAndServe(addr string, readMsg OnMsgReadHandler, handleMsg OnMsgHandleHandler) error { 181 server := &Server{Addr: addr, onMsgReadHandler: readMsg, onMsgHandleHandler: handleMsg} 182 return server.ListenAndServe() 183 }