gost/pkg/service/service.go
2021-11-08 22:06:42 +08:00

71 lines
1.2 KiB
Go

package service
import (
"context"
"net"
"time"
"github.com/go-gost/gost/pkg/handler"
"github.com/go-gost/gost/pkg/listener"
"github.com/go-gost/gost/pkg/logger"
)
type Service struct {
listener listener.Listener
handler handler.Handler
logger logger.Logger
}
func (s *Service) WithListener(ln listener.Listener) *Service {
s.listener = ln
return s
}
func (s *Service) WithHandler(h handler.Handler) *Service {
s.handler = h
return s
}
func (s *Service) WithLogger(logger logger.Logger) *Service {
s.logger = logger
return s
}
func (s *Service) Addr() net.Addr {
return s.listener.Addr()
}
func (s *Service) Run() error {
return s.serve()
}
func (s *Service) Close() error {
return s.listener.Close()
}
func (s *Service) serve() error {
var tempDelay time.Duration
for {
conn, e := s.listener.Accept()
if e != nil {
if ne, ok := e.(net.Error); ok && ne.Temporary() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
s.logger.Warnf("accept: %v, retrying in %v", e, tempDelay)
time.Sleep(tempDelay)
continue
}
return e
}
tempDelay = 0
go s.handler.Handle(context.Background(), conn)
}
}