package main import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "github.com/robfig/cron/v3" "io" "log" "os" "strings" "videoplayer/dao" "videoplayer/handler" "videoplayer/proto" "videoplayer/worker" ) func main() { gin.SetMode(gin.ReleaseMode) r := gin.Default() err := dao.Init() if err != nil { panic("failed to connect database:" + err.Error()) } err = worker.InitRedis() if err != nil { panic("failed to connect redis:" + err.Error()) } r.Use(handler.CrosHandler()) r.Use(JWTAuthMiddleware()) // 使用 JWT 认证中间件 handler.SetUpVideoGroup(r) // Video handler.SetUpUserGroup(r) // User handler.SetUpDeviceGroup(r) // Device handler.SetUpIMGroup(r) // IM handler.SetUpCIDGroup(r) // CID,持续集成、部署 handler.SetUpToolGroup(r) // Tool defer dao.Close() defer worker.CloseRedis() //定时任务 c := cron.New(cron.WithSeconds()) // 添加每 10 秒执行一次的任务 _, err = c.AddFunc("@every 10s", myTask) if err != nil { log.Fatal("添加定时任务失败: ", err) } c.Start() r.Run(":8083") // listen and serve on 0.0.0.0:8083 } func init() { // 创建cid的目录 os.MkdirAll(proto.CID_BASE_DIR, os.ModePerm) os.MkdirAll(proto.CID_BASE_DIR+"script", os.ModePerm) os.MkdirAll(proto.CID_BASE_DIR+"workspace", os.ModePerm) //读取配置文件 //文件地址/home/videoplayer/vp.conf configPath := "/home/videoplayer/vp.conf" //读取配置文件 err := proto.ReadConfig(configPath) if err != nil { panic("failed to read config file:" + err.Error()) } } func writeLogger(c *gin.Context) { ip := c.ClientIP() method := c.Request.Method path := c.Request.URL.Path params := "" if method == "GET" { params = c.Request.URL.RawQuery } if method == "POST" && !strings.Contains(c.Request.URL.Path, "/upload") { params = c.Request.PostForm.Encode() if params == "" { // 请求体 bodyBytes, _ := io.ReadAll(c.Request.Body) c.Request.Body = io.NopCloser(strings.NewReader(string(bodyBytes))) // Write body back, so other handler can read it too params = string(bodyBytes) } } if strings.Contains(c.Request.URL.Path, "/upload") { params = "upload file" } go dao.InsertLogToDB(path, ip, method, params) } func JWTAuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { writeLogger(c) // 从请求头中获取 JWT 令牌 tokenString := c.Request.Header.Get("token") //请求方式为get时,从url中获取token if tokenString == "" { tokenString = c.Query("token") } //如果请求为login或register,则不需要验证token for k, _ := range proto.Url_map { if strings.Contains(c.Request.URL.Path, k) { c.Next() return } } if tokenString == "" { //c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "Unauthorized", "error": "token is empty", "code": proto.TokenIsNull, }) return } if proto.Config.TOKEN_USE_REDIS { redisToken := worker.GetRedis(tokenString) if redisToken == "" { c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "NOT_LOGIN", "error": "server token is empty", "code": proto.TokenIsNull, }) return } } // 使用加密secret 解析 JWT 令牌 token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { return proto.SigningKey, nil }) // 验证令牌 if err != nil || !token.Valid { c.AbortWithStatus(200) c.JSON(200, gin.H{ "message": "NOT_LOGIN", "error": "Invalid token", "code": proto.TokenExpired, }) return } // 将用户信息添加到上下文中 c.Set("id", token.Claims.(jwt.MapClaims)["id"]) c.Set("username", token.Claims.(jwt.MapClaims)["username"]) // 继续处理请求 c.Next() } } func myTask() { // 定时任务 //redis中取出数据 handler.RunCron() }