package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/edu-cloud/push-gateway/internal/config" "github.com/edu-cloud/push-gateway/internal/hub" "github.com/edu-cloud/push-gateway/internal/ws" "github.com/gin-gonic/gin" ) func main() { cfg := config.Load() gin.SetMode(gin.ReleaseMode) h := hub.NewHub() wsHandler := ws.NewHandler(h, cfg.JWTSecret) r := gin.New() r.Use(gin.Recovery()) r.GET("/healthz", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok", "service": "push-gateway"}) }) // WebSocket 升级端点 r.GET("/ws", wsHandler.HandleWebSocket) // 内部推送 API(Msg 服务调用) api := r.Group("/internal") api.POST("/push", wsHandler.PushHandler) srv := &http.Server{ Addr: ":" + cfg.Port, Handler: r, ReadTimeout: 10 * time.Second, WriteTimeout: 60 * time.Second, // WebSocket 长连接 } go func() { log.Printf("Push Gateway listening on :%s", cfg.Port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %s\n", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down Push Gateway...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server forced to shutdown:", err) } }