package router import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "bet24.com/servers/micros/audioroom/callback" "bet24.com/servers/micros/audioroom/config" "bet24.com/servers/micros/audioroom/middleware" "github.com/gin-gonic/gin" "github.com/mattn/go-colorable" ) func Run() { // 强制日志颜色化 gin.ForceConsoleColor() // 设置颜色输出,识别 console 色值 gin.DefaultWriter = colorable.NewColorableStdout() // 设置日志模式 gin.SetMode(gin.DebugMode) // 创建一个默认的路由 r := gin.Default() r.Use(middleware.CheckValid(), middleware.Cors()) // 创建一个默认的路由(HTTPS) rTls := gin.Default() rTls.Use(middleware.TlsHandler(), middleware.CheckValid(), middleware.Cors()) // 处理SSL的中间件 // 回调处理 callbackTls := rTls.Group("/callback") { // 房间创建 callbackTls.POST("/createRoom", callback.CreateRoom) // 房间创建 callbackTls.GET("/createRoom", callback.CreateRoom) // 登录房间 callbackTls.POST("/loginRoom", callback.LoginRoom) // 登录房间 callbackTls.GET("/loginRoom", callback.LoginRoom) // 退出房间 callbackTls.POST("/logoutRoom", callback.LogoutRoom) // 退出房间 callbackTls.GET("/logoutRoom", callback.LogoutRoom) // 流创建回调(上麦) callbackTls.POST("/streamCreate", callback.StreamCreate) // 流创建回调(上麦) callbackTls.GET("/streamCreate", callback.StreamCreate) // 流关闭回调(下麦) callbackTls.POST("/streamClose", callback.StreamClose) // 流关闭回调(下麦) callbackTls.GET("/streamClose", callback.StreamClose) } // ------------------------------404错误------------------------------ // 404错误 r.NoRoute(callback.NotFoundRoute) r.NoMethod(callback.NotFoundMethod) // 启动HTTPS服务(gin默认启动服务) go rTls.RunTLS(fmt.Sprintf(":%d", config.Server.TlsPort), config.Server.TlsCert, config.Server.TlsKey) // 启动HTTP服务(gin默认启动服务) r.Run(fmt.Sprintf(":%d", config.Server.WebPort)) // ------------------------------优雅关机------------------------------ // 实现优雅的关机 srv := &http.Server{ Addr: fmt.Sprintf("%d", config.Server.WebPort), Handler: r, } go func() { fmt.Printf("Listening and serving HTTP on %v\n", srv.Addr) // 启动HTTP服务 if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %s\n", err) } }() // 等待中断信号来优雅地关闭服务器,为关闭服务器操作设置一个超时时长 quit := make(chan os.Signal, 1) // 创建一个接收信号的通道 // kill 默认会发送 syscall.SIGTERM 信号 // kill -2 发送 syscall.SIGINT 信号,我们常用的 Ctrl+C 就是触发系统SIGINT信号 // kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它 // signal.notify 把收到的 syscall.SIGINT 或 syscall.SIGTERM 信号转发给 quit signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞 <-quit // 阻塞在此,当接收到上述两种信号时才会往下执行 fmt.Println("Shutdown Server!") // 创建一个30秒超时的context ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // 优雅关闭服务(将未处理完的请求处理完再关闭服务),超时就退出 if err := srv.Shutdown(ctx); err != nil { log.Fatal("Server Shutdown:", err) } fmt.Println("audioroom server closed ...") }