Files
Archive/echo/internal/transporter/raw.go
2024-07-21 20:29:05 +02:00

98 lines
2.0 KiB
Go

// nolint: errcheck
package transporter
import (
"context"
"net"
"time"
"github.com/Ehco1996/ehco/internal/constant"
"github.com/Ehco1996/ehco/internal/lb"
"github.com/Ehco1996/ehco/internal/metrics"
"github.com/Ehco1996/ehco/internal/relay/conf"
"go.uber.org/zap"
)
var (
_ RelayClient = &RawClient{}
_ RelayServer = &RawServer{}
)
type RawClient struct {
dialer *net.Dialer
cfg *conf.Config
l *zap.SugaredLogger
}
func newRawClient(cfg *conf.Config) (*RawClient, error) {
r := &RawClient{
l: zap.S().Named("raw"),
cfg: cfg,
dialer: &net.Dialer{Timeout: constant.DialTimeOut},
}
return r, nil
}
func (raw *RawClient) TCPHandShake(remote *lb.Node) (net.Conn, error) {
t1 := time.Now()
rc, err := raw.dialer.Dial("tcp", remote.Address)
if err != nil {
return nil, err
}
latency := time.Since(t1)
metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds()))
remote.HandShakeDuration = latency
return rc, nil
}
func (raw *RawClient) HealthCheck(ctx context.Context, remote *lb.Node) error {
l := zap.S().Named("health-check")
l.Infof("start send req to %s", remote.Address)
c, err := raw.TCPHandShake(remote)
if err != nil {
l.Errorf("send req to %s meet error:%s", remote.Address, err)
return err
}
c.Close()
return nil
}
type RawServer struct {
*baseTransporter
lis *net.TCPListener
}
func newRawServer(base *baseTransporter) (*RawServer, error) {
addr, err := base.GetTCPListenAddr()
if err != nil {
return nil, err
}
lis, err := net.ListenTCP("tcp", addr)
if err != nil {
return nil, err
}
return &RawServer{
lis: lis,
baseTransporter: base,
}, nil
}
func (s *RawServer) Close() error {
return s.lis.Close()
}
func (s *RawServer) ListenAndServe() error {
for {
c, err := s.lis.AcceptTCP()
if err != nil {
return err
}
go func(c net.Conn) {
defer c.Close()
if err := s.RelayTCPConn(c, s.relayer.TCPHandShake); err != nil {
s.l.Errorf("RelayTCPConn error: %s", err.Error())
}
}(c)
}
}