ipv4v6支持兼容
This commit is contained in:
@@ -3,7 +3,9 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"linkmaster-node/internal/config"
|
"linkmaster-node/internal/config"
|
||||||
"linkmaster-node/internal/handler"
|
"linkmaster-node/internal/handler"
|
||||||
@@ -14,8 +16,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type HTTPServer struct {
|
type HTTPServer struct {
|
||||||
server *http.Server
|
ipv4Server *http.Server
|
||||||
|
ipv6Server *http.Server
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPServer(cfg *config.Config) *HTTPServer {
|
func NewHTTPServer(cfg *config.Config) *HTTPServer {
|
||||||
@@ -43,26 +47,90 @@ func NewHTTPServer(cfg *config.Config) *HTTPServer {
|
|||||||
api.GET("/health", handler.HandleHealth)
|
api.GET("/health", handler.HandleHealth)
|
||||||
}
|
}
|
||||||
|
|
||||||
server := &http.Server{
|
// IPv4 服务器
|
||||||
Addr: fmt.Sprintf(":%d", cfg.Server.Port),
|
ipv4Server := &http.Server{
|
||||||
|
Addr: fmt.Sprintf("0.0.0.0:%d", cfg.Server.Port),
|
||||||
|
Handler: router,
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPv6 服务器
|
||||||
|
ipv6Server := &http.Server{
|
||||||
|
Addr: fmt.Sprintf("[::]:%d", cfg.Server.Port),
|
||||||
Handler: router,
|
Handler: router,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger, _ := zap.NewProduction()
|
logger, _ := zap.NewProduction()
|
||||||
|
|
||||||
return &HTTPServer{
|
return &HTTPServer{
|
||||||
server: server,
|
ipv4Server: ipv4Server,
|
||||||
|
ipv6Server: ipv6Server,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) Start() error {
|
func (s *HTTPServer) Start() error {
|
||||||
s.logger.Info("HTTP服务器启动", zap.String("addr", s.server.Addr))
|
// 启动 IPv4 服务器
|
||||||
return s.server.ListenAndServe()
|
s.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer s.wg.Done()
|
||||||
|
s.logger.Info("HTTP服务器启动 (IPv4)", zap.String("addr", s.ipv4Server.Addr))
|
||||||
|
if err := s.ipv4Server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
|
s.logger.Error("IPv4服务器启动失败", zap.Error(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 启动 IPv6 服务器
|
||||||
|
s.wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer s.wg.Done()
|
||||||
|
// 检查系统是否支持 IPv6
|
||||||
|
listener, err := net.Listen("tcp6", s.ipv6Server.Addr)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("IPv6不支持或已禁用,跳过IPv6监听", zap.String("addr", s.ipv6Server.Addr), zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.logger.Info("HTTP服务器启动 (IPv6)", zap.String("addr", s.ipv6Server.Addr))
|
||||||
|
if err := s.ipv6Server.Serve(listener); err != nil && err != http.ErrServerClosed {
|
||||||
|
s.logger.Error("IPv6服务器启动失败", zap.Error(err))
|
||||||
|
}
|
||||||
|
// Serve 返回后关闭监听器
|
||||||
|
listener.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 立即返回,服务器在后台运行
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTPServer) Shutdown(ctx context.Context) error {
|
func (s *HTTPServer) Shutdown(ctx context.Context) error {
|
||||||
return s.server.Shutdown(ctx)
|
var errs []error
|
||||||
|
|
||||||
|
// 关闭 IPv4 服务器
|
||||||
|
if s.ipv4Server != nil {
|
||||||
|
if err := s.ipv4Server.Shutdown(ctx); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("关闭IPv4服务器失败: %w", err))
|
||||||
|
} else {
|
||||||
|
s.logger.Info("IPv4服务器已关闭")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭 IPv6 服务器
|
||||||
|
if s.ipv6Server != nil {
|
||||||
|
if err := s.ipv6Server.Shutdown(ctx); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("关闭IPv6服务器失败: %w", err))
|
||||||
|
} else {
|
||||||
|
s.logger.Info("IPv6服务器已关闭")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待所有 goroutine 完成
|
||||||
|
s.wg.Wait()
|
||||||
|
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return fmt.Errorf("关闭服务器时发生错误: %v", errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func recoveryMiddleware(c *gin.Context) {
|
func recoveryMiddleware(c *gin.Context) {
|
||||||
|
|||||||
Reference in New Issue
Block a user