package server import ( "context" "sync" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" v1 "pkg.bing89.com/travebing/api/v1" "pkg.bing89.com/travebing/config" "pkg.bing89.com/travebing/controller" "pkg.bing89.com/travebing/notifier" ) type Server struct { ctrl controller.Controller cfg *config.Config ClientMap map[string]*Clients cmLock sync.RWMutex notifier *notifier.Notifier } func New(cfg *config.Config) (*Server, error) { s := &Server{ cfg: cfg, ClientMap: make(map[string]*Clients), cmLock: sync.RWMutex{}, notifier: notifier.New(), } ctrl, err := controller.New(cfg) if err != nil { return nil, err } s.ctrl = ctrl return s, nil } func (s *Server) AddClient(plan string, conn *websocket.Conn) { s.cmLock.Lock() defer s.cmLock.Unlock() clts, ok := s.ClientMap[plan] if !ok { clts = NewClients() } clts.Set(NewClient(plan, conn)) s.ClientMap[plan] = clts } func (s *Server) Notify(plan string, way v1.TravelWay) error { s.cmLock.Lock() defer s.cmLock.Unlock() clts, ok := s.ClientMap[plan] if !ok { return nil } return clts.Notify(way) } func (s *Server) Run() error { engine := gin.Default() apiGroup := engine.Group("/api/v1") apiGroup.GET("/plans", s.HandlePlanList) apiGroup.POST("/plans", s.HandlePlanCreate) apiGroup.GET("/plans/:plan", s.HandlePlanGet) apiGroup.GET("/plans/:plan/ways", s.HandleWayList) apiGroup.POST("/plans/:plan/ways", s.HandleWayCreate) apiGroup.GET("/plans/:plan/sync", s.HandleWaySync) ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func() { err := s.notifier.Run(ctx) if err != nil { panic(err) } }() return engine.Run(s.cfg.Listen) }