package lc import ( "encoding/xml" "github.com/sirupsen/logrus" "io" "io/ioutil" "lc-smartX/lc/model" "lc-smartX/util" "lc-smartX/util/gopool" "log" "mime/multipart" "net/http" "strings" "time" ) // 单摄像头服务器 func NewCameraEventServer() *CameraServer { camera := util.Config.Cameras[0] // 取第一个摄像头配置 server := &CameraServer{ Camera: camera, Notifier: nil, } return server } type CameraServer struct { Camera model.CameraInfo // 单个摄像头 Notifier Notifier // 单个回调 } // 启动HTTP服务监听摄像头事件 func (s *CameraServer) Start() { http.HandleFunc(util.Config.Server.HikServer.Path, s.Handler) logrus.Fatalf("摄像头事件服务启动失败 %s: %v", util.Config.Server.HikServer.Addr, http.ListenAndServe(util.Config.Server.HikServer.Addr, nil)) } // 注册回调 func (s *CameraServer) RegisterCallback(notifier Notifier) { s.Notifier = notifier } // 触发回调 func (s *CameraServer) Callback(text string) { if s.Notifier == nil { logrus.Error("摄像头回调未注册") return } s.Notifier.Notify(text, 1, 0) logrus.Debugf("摄像头 %s 触发事件", s.Camera.IP) } // HTTP请求处理(保持原有逻辑,适配单设备) func (s *CameraServer) Handler(w http.ResponseWriter, r *http.Request) { gopool.Go(func() { w.WriteHeader(200) w.Header().Add("Date", time.Now().String()) w.Header().Add("Connection", "keep-alive") }) contentType := r.Header.Get("Content-Type") if strings.Contains(contentType, "application/xml") { bytes, err := io.ReadAll(r.Body) if err != nil { return } var event model.EventNotificationAlert if err := xml.Unmarshal(bytes, &event); err != nil { return } for _, v := range event.DetectionRegionList.DetectionRegionEntry { s.Callback(v.RegionID) } } else if strings.Contains(contentType, "multipart/form-data") { s.HandleMultipart(r) } } func (s *CameraServer) HandleMultipart(r *http.Request) { multipartReader := multipart.NewReader(r.Body, "boundary") var event model.EventNotificationAlert for { part, err := multipartReader.NextPart() if err == io.EOF { break } if err != nil { log.Println("读取multipart错误:", err) return } if part.FormName() != "linedetectionImage" || !strings.Contains(part.FormName(), "Image") { xmlData, err := ioutil.ReadAll(part) if err != nil { return } xml.Unmarshal(xmlData, &event) continue } } s.Callback("") }