deviceMgr.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package tcp
  2. import (
  3. "encoding/hex"
  4. "errors"
  5. "fmt"
  6. "go.uber.org/zap"
  7. "gorm.io/gorm"
  8. "net"
  9. Dev "server/dao/devices"
  10. deviceDao "server/dao/devices"
  11. promodel "server/model/common/devices"
  12. "server/model/common/request"
  13. "server/protocol"
  14. "server/utils/logger"
  15. "strings"
  16. "time"
  17. )
  18. var (
  19. devices = make(map[string]Device) // 存储连接的全局 map
  20. )
  21. type Device struct {
  22. info deviceDao.Screens
  23. conn net.Conn
  24. lastTime time.Time
  25. stopChan chan struct{} // 添加停止通道
  26. }
  27. func (s *Device) Start(conn net.Conn) {
  28. s.conn = conn
  29. s.stopChan = make(chan struct{})
  30. go s.Process()
  31. go s.Handle()
  32. }
  33. func (s *Device) Process() {
  34. // 函数执行完之后关闭连接
  35. defer s.conn.Close()
  36. for {
  37. buf := make([]byte, 256)
  38. // 将tcp连接读取到的数据读取到byte数组中, 返回读取到的byte的数目
  39. n, err := s.conn.Read(buf)
  40. if err != nil {
  41. // 从客户端读取数据的过程中发生错误
  42. logger.Logger.Errorf("read from client failed, err:%v", err)
  43. break
  44. }
  45. data := hex.EncodeToString(buf[:n])
  46. if !strings.Contains(strings.ToLower(data), "fe5c4b89") {
  47. continue
  48. }
  49. switch data[16:18] {
  50. case "61":
  51. logger.Logger.Debug("登录")
  52. // fe5c4b89 2a000000 62 00000000 17000000 31 23 32303233(年) 3035(月) 3135(日) 3031(星期) 3038(时) 3334(分) 3135(秒) 23 303630(心跳包时间) 23 ffff
  53. buffer := protocol.AuthDataPack{}.AuthLogin()
  54. // 通过sn 查设备是否存在 不存在return 存在就保存con 和 info
  55. screens, err := deviceDao.QueryScreenBySn(data[34:50])
  56. if errors.Is(err, gorm.ErrRecordNotFound) {
  57. logger.Logger.Errorf("Process SN not found \n")
  58. break
  59. }
  60. s.info = screens
  61. devices[s.info.Sn] = *s
  62. s.conn.Write(buffer.Bytes())
  63. case "91":
  64. logger.Logger.Debug("心跳")
  65. if data[34:50] != s.info.Sn {
  66. continue
  67. }
  68. s.UpdateInfo(data[82:84], data[86:88], data[90:92])
  69. default:
  70. fmt.Println("读取:", data)
  71. }
  72. }
  73. }
  74. func (s *Device) Handle() {
  75. defer s.conn.Close()
  76. t2 := time.NewTicker(3 * time.Minute) //在线监测
  77. defer t2.Stop()
  78. for {
  79. select {
  80. case <-t2.C:
  81. state := request.DeviceStatus{
  82. Status: 1,
  83. PlayStatus: 1,
  84. DisplayStatus: 1,
  85. SourceStatus: 1,
  86. }
  87. if time.Now().Add(-2*time.Minute).After(s.lastTime) && !s.lastTime.IsZero() {
  88. //离线
  89. state.Status = 0
  90. state.PlayStatus = 0
  91. state.DisplayStatus = 0
  92. state.SourceStatus = 0
  93. err := Dev.UpdateScreensStatus(s.info.ScreensCode, state)
  94. if err != nil {
  95. logger.Logger.Error("UpdateScreensStatus err", zap.Error(err))
  96. continue
  97. }
  98. s.conn.Close()
  99. close(s.stopChan) // 通知协程停止
  100. return // 结束 Handle 协程
  101. } else {
  102. logger.Logger.Debugf("%s在线", s.info.ScreensCode)
  103. }
  104. //修改数据库状态
  105. err := Dev.UpdateScreensStatus(s.info.ScreensCode, state)
  106. if err != nil {
  107. logger.Logger.Error("UpdateScreensStatus err", zap.Error(err))
  108. continue
  109. }
  110. break
  111. default:
  112. continue
  113. }
  114. }
  115. }
  116. func (s *Device) UpdateInfo(playStatus, displayStatus, sourceStatus string) {
  117. play, display, source := 0, 0, 0
  118. if playStatus == "31" {
  119. play = 1
  120. }
  121. if displayStatus == "30" {
  122. display = 1
  123. }
  124. if sourceStatus == "30" {
  125. source = 1
  126. }
  127. s.info.Status = 1
  128. s.info.PlayStatus = play
  129. s.info.DisplayStatus = display
  130. s.info.SourceStatus = source
  131. s.lastTime = time.Now()
  132. }
  133. func (s *Device) SwitchScreen(onOff int) error {
  134. pack := protocol.SwitchDataPack{Type: 0x52} //熄屏
  135. if onOff == 1 {
  136. pack = protocol.SwitchDataPack{Type: 0x51} //亮屏
  137. }
  138. buf := pack.SwitchScreens() //获取开关屏指令
  139. _, err := s.conn.Write(buf.Bytes())
  140. if err != nil {
  141. logger.Logger.Errorf("SwitchScreen write failed, err:%v", err)
  142. return err
  143. }
  144. return nil
  145. }
  146. func (s *Device) SendInternalCode(content []promodel.InternalCodeContent) error {
  147. pack := protocol.InternalCodeDataPack{}
  148. //获取要写入连接的字节数组
  149. buf := pack.SendInternalCode(content)
  150. _, err := s.conn.Write(buf.Bytes())
  151. if err != nil {
  152. logger.Logger.Errorf("SendInternalCode write failed, err:%v", err)
  153. return err
  154. }
  155. return nil
  156. }
  157. func (s *Device) VoiceBroad(broad string) error {
  158. pack := protocol.VoiceBroadDataPack{}
  159. buf := pack.VoiceBroad(broad)
  160. _, err := s.conn.Write(buf.Bytes())
  161. if err != nil {
  162. logger.Logger.Errorf("VoiceBroad write failed, err:%v", err)
  163. return err
  164. }
  165. return nil
  166. }
  167. // 向外暴露的开关操作
  168. func SwitchScreen(sn string, onOff int) error {
  169. device := devices[sn]
  170. err := device.SwitchScreen(onOff)
  171. if err != nil {
  172. return err
  173. }
  174. return nil
  175. }
  176. // 向外暴露的发送内码文字操作
  177. func SendInternalCode(sn string, content []promodel.InternalCodeContent) error {
  178. device := devices[sn]
  179. err := device.SendInternalCode(content)
  180. if err != nil {
  181. return err
  182. }
  183. return nil
  184. }
  185. // 向外暴露的远程喊话操作
  186. func VoiceBroad(sn string, broad string) error {
  187. device := devices[sn]
  188. err := device.VoiceBroad(broad)
  189. if err != nil {
  190. return err
  191. }
  192. return nil
  193. }