| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- package main
- import (
- "context"
- "fwh-toolbox-server/cache"
- "fwh-toolbox-server/config"
- "fwh-toolbox-server/controllers"
- "fwh-toolbox-server/database"
- "fwh-toolbox-server/repositories"
- "fwh-toolbox-server/repositories/api/fwh_pro"
- "fwh-toolbox-server/repositories/api/fwh_test"
- "fwh-toolbox-server/task"
- "fwh-toolbox-server/utils/casdoor"
- "fwh-toolbox-server/utils/minio"
- "log"
- "net"
- "net/http"
- "os"
- "os/signal"
- // "fwh-toolbox-server/database"
- _ "fwh-toolbox-server/docs" // swag 自动生成文档
- "fwh-toolbox-server/logger"
- "fwh-toolbox-server/routes"
- "fwh-toolbox-server/scheduler"
- "fwh-toolbox-server/networkEvents"
- "github.com/gofiber/fiber/v2"
- "github.com/gofiber/swagger"
- "github.com/hibiken/asynq"
- "github.com/hibiken/asynqmon"
- "go.uber.org/zap"
- "golang.org/x/sys/unix"
- )
- func main() {
- var cfg *config.Config
- var err error
- cfg, err = config.LoadConfig()
- if err != nil {
- panic(err)
- }
- err = logger.Init(cfg.App.AppEnv, cfg.App.LogLevel)
- if err != nil {
- panic(err)
- }
- defer logger.Log.Sync() // 退出前同步zap缓冲区
- // 初始化数据库
- err = database.Init(&cfg.App)
- if err != nil {
- zap.L().Error("database init failed.", zap.String("err", err.Error()))
- panic(err)
- }
- // 初始化缓存
- cache.Init(cfg.App.RedisAddr)
- // 初始化Minio
- minio.InitClient(&cfg.App)
- // 初始化 Repository migration/index;必须在 scheduler/worker 之前完成。
- if err = repositories.Init(context.Background()); err != nil {
- zap.L().Error("repository init failed", zap.String("err", err.Error()))
- panic(err)
- }
- // 初始化FwhApi
- repositories.FwhHttpInit(&cfg.FwhApi)
- // 初始化FwhTestApi(测试环境)
- repositories.FwhTestHttpInit(&cfg.FwhTestApi)
- // 初始化Fwh ES(iotcore-stat 报文统计)
- repositories.EsHttpInit(&cfg.FwhEs)
- // 初始化PlaneApi
- repositories.PlaneHttpInit(&cfg.PlaneApi)
- // 初始化PlaneWebApi
- // 初始化新架构 Plane(PlaneClient + PlaneService)
- repositories.InitPlane(&cfg.PlaneWebApi)
- // 初始化计划任务
- scheduler.Init()
- // 初始化任务
- task.InitTask(task.TaskRedisOpt{
- Addr: cfg.App.RedisAddr,
- DB: 12,
- })
- // 初始化Casdoor
- casdoor.InitAuthConfig()
- // 初始化FWH MQTT客户端
- repositories.FwhMqttInit(&cfg.FwhMqtt)
- // repositories.FwhMqttFaultRecordChargeChannel(context.Background(), "10060005A03X25160385")
- app := fiber.New()
- app.Use(func(c *fiber.Ctx) error {
- logger.Log.Info("请求", zap.String("path", c.Path()))
- return c.Next()
- })
- // 注册 Swagger 路由
- app.Get("/swagger/*", swagger.HandlerDefault)
- routes.Setup(app)
- // TOTP 页面使用独立端口,不占用主 APP 的路由。
- var totpApp *fiber.App
- if cfg.FwhApi.FwhTotpSecret != "" && cfg.App.TotpViewPassword != "" {
- if cfg.App.TotpViewPort == cfg.App.AppPort {
- panic("FWH_TOTP_VIEW_PORT must differ from APP_PORT")
- }
- totpApp = fiber.New()
- routes.TotpViewSetup(totpApp, cfg.FwhApi.FwhTotpSecret, cfg.App.TotpViewPassword)
- go func() {
- addr := net.JoinHostPort(cfg.App.TotpViewHost, cfg.App.TotpViewPort)
- if err := totpApp.Listen(addr); err != nil {
- zap.L().Error("TOTP view port listening failed", zap.String("addr", addr), zap.Error(err))
- panic(err)
- }
- }()
- }
- // 初始化 AI Chat (ACP Client)
- controllers.InitAIChat(".", cfg.Kiro.RunAsUser, cfg.Kiro.Home, cfg.Kiro.DebugLog)
- // 启动第一个监听
- go func() {
- if err := networkEvents.InitEvio(); err != nil {
- zap.L().Error("networkEvents init failed.", zap.String("err", err.Error()))
- panic(err)
- }
- }()
- // 启动Asynqmon界面
- go func() {
- h := asynqmon.New(asynqmon.Options{
- RootPath: "/asynqmon", // RootPath specifies the root for asynqmon app
- RedisConnOpt: asynq.RedisClientOpt{Addr: cfg.App.RedisAddr, DB: 12},
- })
- // Note: We need the tailing slash when using net/http.ServeMux.
- http.Handle("/", h)
- listenAddr := "0.0.0.0:" + cfg.App.AsynqmonPort
- // Go to http://localhost:8080/asynqmon to see asynqmon homepage.
- err = http.ListenAndServe(listenAddr, nil)
- if err != nil {
- zap.L().Error("Asynqmon port listening failed.", zap.String("err", err.Error()))
- panic(err)
- }
- log.Println("asynqmon shutdown finished")
- zap.L().Info("Asynqmon started successfully.", zap.String("addr", listenAddr))
- }()
- // 提前登录FWH
- err = fwh_pro.Login()
- if err != nil {
- zap.L().Error("FWH login failed.", zap.String("err", err.Error()))
- // panic(err)
- }
- // 提前登录FWH测试环境
- err = fwh_test.Login()
- if err != nil {
- zap.L().Error("FWH test login failed.", zap.String("err", err.Error()))
- // panic(err)
- }
- // TEST
- // err = task.CreateTaskSimCardCollect()
- // if err != nil {
- // zap.L().Error("CreateTaskSimCardCollect failed.", zap.String("err", err.Error()), zap.String("time(UTC)", time.Now().UTC().Format(time.DateTime)))
- // }
- go func() {
- sigs := make(chan os.Signal, 1)
- signal.Notify(sigs, unix.SIGTERM, unix.SIGINT)
- <-sigs
- log.Println("fiber shutdown")
- if totpApp != nil {
- _ = totpApp.Shutdown()
- }
- app.Shutdown()
- }()
- err = app.Listen("localhost:" + cfg.App.AppPort)
- if err != nil {
- zap.L().Error("Port listening failed.", zap.String("err", err.Error()))
- panic(err)
- }
- }
|