eventServer.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package eventServer
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "github.com/sirupsen/logrus"
  6. mail "github.com/xhit/go-simple-mail/v2"
  7. "io"
  8. "io/ioutil"
  9. "lcfns/model/app"
  10. "lcfns/service"
  11. "log"
  12. "mime/multipart"
  13. "net/http"
  14. "strings"
  15. "time"
  16. )
  17. // MQDEvent (MQTT Data Event) 用于mqtt传输事件
  18. type MQDEvent struct {
  19. EventCode string `json:"eventCode"`
  20. EId int `json:"eId"`
  21. Ip string `json:"ip"`
  22. Type string `json:"type"`
  23. StartTime string `json:"startTime"`
  24. Name string `json:"name"`
  25. Data []byte `json:"data"`
  26. }
  27. func StartEventServer() {
  28. http.HandleFunc("/event", handler)
  29. logrus.Fatal("事件监听服务启动失败", http.ListenAndServe(":8850", nil))
  30. }
  31. func handler(w http.ResponseWriter, r *http.Request) {
  32. go func() {
  33. //监听主机应答固定,直接先应答
  34. w.WriteHeader(200)
  35. w.Header().Add("Date", time.Now().String())
  36. w.Header().Add("Connection", "close")
  37. }()
  38. //logRequest(r)
  39. contentType := r.Header.Get("Content-Type")
  40. if strings.Contains(contentType, "application/xml") {
  41. bytes, err := ioutil.ReadAll(r.Body)
  42. if err != nil {
  43. logrus.Error("事件处理-读取错误:", err)
  44. return
  45. }
  46. var event EventNotificationAlert
  47. err = xml.Unmarshal(bytes, &event)
  48. if err != nil {
  49. logrus.Error("事件处理-解析错误:", err)
  50. return
  51. }
  52. //处理事件 todo 邮箱
  53. fmt.Println("application/xml 事件")
  54. handleEvent_(event)
  55. } else if strings.Contains(contentType, "multipart/form-data") {
  56. fmt.Println("multipart/form-data 事件")
  57. handleMultipart(r)
  58. } else {
  59. logrus.WithField("Content-Type", contentType).Error("该Content-Type没有写处理逻辑")
  60. return
  61. }
  62. }
  63. //TODO 限制事件重复触发,一段时间内不重复发送邮件,但保持报警状态
  64. var eventService = service.ServiceGroupApp.AppServiceGroup.EventService
  65. // 处理多文件事件
  66. func handleMultipart(r *http.Request) {
  67. // todo 远程联动-ip音柱
  68. multipartReader := multipart.NewReader(r.Body, "boundary")
  69. var msg string //邮件消息
  70. // 循环读取每个 part
  71. var eventAlert EventNotificationAlert
  72. for {
  73. part, err := multipartReader.NextPart()
  74. //defer part.Close()
  75. if err == io.EOF {
  76. break
  77. }
  78. if err != nil {
  79. log.Println("Failed to read part:", err)
  80. continue
  81. }
  82. // 检查 part 的 Content-Disposition
  83. formName := part.FormName()
  84. //fmt.Println("formName", formName)
  85. if !strings.Contains(formName, "Image") {
  86. //不含图片的xml部分数据
  87. xmlData, err := ioutil.ReadAll(part)
  88. if err != nil {
  89. return
  90. }
  91. //fmt.Printf("xml:%s\n", string(xmlData))
  92. xml.Unmarshal(xmlData, &eventAlert)
  93. //event.Ip = eventAlert.IpAddress
  94. //event.Type = eventAlert.EventType
  95. //event.StartTime = eventAlert.DateTime
  96. msg = handleEvent_(eventAlert)
  97. continue
  98. }
  99. //fmt.Printf("eventAlert:%+v\n", eventAlert)
  100. //处理图片部分数据
  101. contentType := part.Header.Get("Content-Type")
  102. eventCode := part.Header.Get("Content-ID")
  103. picName := timeFmt(eventAlert.DateTime) + ".jpeg"
  104. //event.Name = picName
  105. data, _ := ioutil.ReadAll(part)
  106. f := &mail.File{
  107. Name: picName,
  108. MimeType: contentType,
  109. Data: data,
  110. Inline: true,
  111. }
  112. picture := &app.Picture{
  113. Name: picName,
  114. Time: time.Now(),
  115. Mime: contentType,
  116. Size: len(data),
  117. }
  118. pictureData := &app.PictureData{
  119. Data: data,
  120. }
  121. event := &app.Event{
  122. EventCode: eventCode,
  123. MacAddress: eventAlert.MacAddress,
  124. EventType: eventAlert.EventType,
  125. }
  126. fmt.Printf("事件信息:%+v\n", eventAlert)
  127. //保存图片
  128. go eventService.Save(event, picture, pictureData)
  129. //邮件通知
  130. SendAlarmEmail(eventAlert.MacAddress, msg, f)
  131. //utils.EmailPicture("1104038181@qq.com",
  132. // "防溺水通知",
  133. // "",
  134. // f)
  135. }
  136. }
  137. func handleEvent_(event EventNotificationAlert) string {
  138. var eType string
  139. if event.EventType == "duration" {
  140. eType = event.DurationList.Duration[0].RelationEvent
  141. } else {
  142. eType = event.EventType
  143. }
  144. return fmt.Sprintf("事件类型:%s,时间:%s", sMap[eType], timeFmt(event.DateTime))
  145. }
  146. func timeFmt(str string) string {
  147. s := strings.Split(str, "T")
  148. t := s[0]
  149. s1 := strings.Split(s[1], ".")
  150. s2 := strings.Split(s1[0], "+")
  151. return t + " " + s2[0]
  152. }
  153. func logRequest(req *http.Request) {
  154. // 打印请求行
  155. fmt.Printf("%s %s %s\n", req.Method, req.URL.Path, req.Proto)
  156. // 打印请求头
  157. for name, headers := range req.Header {
  158. for _, h := range headers {
  159. fmt.Printf("%v: %v\n", name, h)
  160. }
  161. }
  162. // 打印请求体
  163. body, _ := ioutil.ReadAll(req.Body)
  164. fmt.Printf("%s\n", body)
  165. }