camera_event.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package lc
  2. import (
  3. "encoding/xml"
  4. "github.com/sirupsen/logrus"
  5. "io"
  6. "io/ioutil"
  7. "lc-smartX/lc/model"
  8. "lc-smartX/util"
  9. "lc-smartX/util/gopool"
  10. "log"
  11. "mime/multipart"
  12. "net/http"
  13. "strings"
  14. "time"
  15. )
  16. // 单摄像头服务器
  17. func NewCameraEventServer() *CameraServer {
  18. camera := util.Config.Cameras[0] // 取第一个摄像头配置
  19. server := &CameraServer{
  20. Camera: camera,
  21. Notifier: nil,
  22. }
  23. return server
  24. }
  25. type CameraServer struct {
  26. Camera model.CameraInfo // 单个摄像头
  27. Notifier Notifier // 单个回调
  28. }
  29. // 启动HTTP服务监听摄像头事件
  30. func (s *CameraServer) Start() {
  31. http.HandleFunc(util.Config.Server.HikServer.Path, s.Handler)
  32. logrus.Fatalf("摄像头事件服务启动失败 %s: %v", util.Config.Server.HikServer.Addr,
  33. http.ListenAndServe(util.Config.Server.HikServer.Addr, nil))
  34. }
  35. // 注册回调
  36. func (s *CameraServer) RegisterCallback(notifier Notifier) {
  37. s.Notifier = notifier
  38. }
  39. // 触发回调
  40. func (s *CameraServer) Callback(text string) {
  41. if s.Notifier == nil {
  42. logrus.Error("摄像头回调未注册")
  43. return
  44. }
  45. s.Notifier.Notify(text, 1, 0)
  46. logrus.Debugf("摄像头 %s 触发事件", s.Camera.IP)
  47. }
  48. // HTTP请求处理(保持原有逻辑,适配单设备)
  49. func (s *CameraServer) Handler(w http.ResponseWriter, r *http.Request) {
  50. gopool.Go(func() {
  51. w.WriteHeader(200)
  52. w.Header().Add("Date", time.Now().String())
  53. w.Header().Add("Connection", "keep-alive")
  54. })
  55. contentType := r.Header.Get("Content-Type")
  56. if strings.Contains(contentType, "application/xml") {
  57. bytes, err := io.ReadAll(r.Body)
  58. if err != nil {
  59. return
  60. }
  61. var event model.EventNotificationAlert
  62. if err := xml.Unmarshal(bytes, &event); err != nil {
  63. return
  64. }
  65. for _, v := range event.DetectionRegionList.DetectionRegionEntry {
  66. s.Callback(v.RegionID)
  67. }
  68. } else if strings.Contains(contentType, "multipart/form-data") {
  69. s.HandleMultipart(r)
  70. }
  71. }
  72. func (s *CameraServer) HandleMultipart(r *http.Request) {
  73. multipartReader := multipart.NewReader(r.Body, "boundary")
  74. var event model.EventNotificationAlert
  75. for {
  76. part, err := multipartReader.NextPart()
  77. if err == io.EOF {
  78. break
  79. }
  80. if err != nil {
  81. log.Println("读取multipart错误:", err)
  82. return
  83. }
  84. if part.FormName() != "linedetectionImage" || !strings.Contains(part.FormName(), "Image") {
  85. xmlData, err := ioutil.ReadAll(part)
  86. if err != nil {
  87. return
  88. }
  89. xml.Unmarshal(xmlData, &event)
  90. continue
  91. }
  92. }
  93. s.Callback("")
  94. }