hi-server/internal/server.go
shanshanzhong 7914b2aa78
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m51s
shouldBindJson 使用错误
2026-03-06 01:30:39 -08:00

160 lines
3.9 KiB
Go

package internal
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net/http"
"os"
"time"
"github.com/perfect-panel/server/internal/report"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/proc"
"github.com/perfect-panel/server/pkg/trace"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/redis"
"github.com/gin-gonic/gin"
"github.com/perfect-panel/server/initialize"
"github.com/perfect-panel/server/internal/handler"
"github.com/perfect-panel/server/internal/middleware"
"github.com/perfect-panel/server/internal/svc"
)
type Service struct {
server *http.Server
svc *svc.ServiceContext
}
func NewService(svc *svc.ServiceContext) *Service {
return &Service{
svc: svc,
}
}
func initServer(svc *svc.ServiceContext) *gin.Engine {
// start init system config
initialize.StartInitSystemConfig(svc)
// init gin server
r := gin.Default()
r.RemoteIPHeaders = []string{"X-Original-Forwarded-For", "X-Forwarded-For", "X-Real-IP"}
// init session
sessionStore, err := redis.NewStore(10, "tcp", svc.Config.Redis.Host, svc.Config.Redis.Pass, []byte(svc.Config.JwtAuth.AccessSecret))
if err != nil {
logger.Errorw("init session error", logger.Field("error", err.Error()))
panic(err)
}
r.Use(sessions.Sessions("ppanel", sessionStore))
// use cors middleware
r.Use(
middleware.TraceMiddleware(svc),
middleware.ApiVersionMiddleware(svc),
middleware.LoggerMiddleware(svc),
middleware.SignatureMiddleware(svc),
middleware.CorsMiddleware,
gin.Recovery(),
)
// register handlers
handler.RegisterHandlers(r, svc)
// register subscribe handler
handler.RegisterSubscribeHandlers(r, svc)
// register telegram handler
handler.RegisterTelegramHandlers(r, svc)
// register notify handler
handler.RegisterNotifyHandlers(r, svc)
return r
}
func (m *Service) Start() {
if m.svc == nil {
panic("config file path is nil")
}
// init service
r := initServer(m.svc)
// get server port
port := m.svc.Config.Port
host := m.svc.Config.Host
// check gateway mode
if report.IsGatewayMode() {
// get free port
freePort, err := report.ModulePort()
if err != nil {
logger.Errorf("get module port error: %s", err.Error())
panic(err)
}
port = freePort
host = "127.0.0.1"
// register module
err = report.RegisterModule(port)
if err != nil {
logger.Errorf("register module error: %s", err.Error())
os.Exit(1)
}
logger.Infof("module registered on port %d", port)
}
serverAddr := fmt.Sprintf("%v:%d", host, port)
m.server = &http.Server{
Addr: serverAddr,
Handler: r,
TLSConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
},
}
traceCfg := m.svc.Config.Trace
if traceCfg.Name == "" {
traceCfg.Name = "ppanel"
}
if traceCfg.Sampler == 0 {
traceCfg.Sampler = 1.0
}
trace.StartAgent(traceCfg)
proc.AddShutdownListener(func() {
trace.StopAgent()
})
m.svc.Restart = m.Restart
logger.Infof("server start at %v", serverAddr)
if m.svc.Config.TLS.Enable {
if err := m.server.ListenAndServeTLS(m.svc.Config.TLS.CertFile, m.svc.Config.TLS.KeyFile); err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Errorf("server start error: %s", err.Error())
}
} else {
if err := m.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
logger.Errorf("server start error: %s", err.Error())
}
}
}
func (m *Service) Stop() {
if m.server == nil {
return
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := m.server.Shutdown(ctx); err != nil {
logger.Errorf("server shutdown error: %s", err.Error())
}
logger.Info("server shutdown")
}
func (m *Service) Restart() error {
if m.server == nil {
return errors.New("server is nil")
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := m.server.Shutdown(ctx); err != nil {
logger.Errorf("server shutdown error: %v", err.Error())
return err
}
logger.Info("server shutdown")
go m.Start()
return nil
}