netmgr.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package netmgr
  2. import "C"
  3. import (
  4. "sync/atomic"
  5. "time"
  6. modem "hnyfkj.com.cn/rtu/bxs-sy/air720u"
  7. "hnyfkj.com.cn/rtu/bxs-sy/baseapp"
  8. mqtt "hnyfkj.com.cn/rtu/bxs-sy/reporter"
  9. )
  10. const MODULE_NAME = "NetworkManager"
  11. var (
  12. isOnline atomic.Bool // 标记是否联网
  13. offlineStartTs atomic.Int64 // 离线开始时间
  14. isSyncNTPTimeOK atomic.Bool // 标记本地时间是否已同步成功
  15. )
  16. const (
  17. interval1 = time.Duration(1) * time.Second
  18. interval2 = time.Duration(5) * time.Second
  19. )
  20. func ModuleInit() {
  21. go serviceRun()
  22. }
  23. // 联网保持服务
  24. func serviceRun() {
  25. t := time.NewTimer(interval1)
  26. defer t.Stop()
  27. for {
  28. select {
  29. case <-t.C:
  30. // 1, 联网检测-看结果
  31. dnsOK, pingOK, tcpOK, httpOK := CheckNetwork()
  32. mqttOK := false
  33. if mqtt.Reporter != nil {
  34. mqttOK = mqtt.Reporter.IsLogin()
  35. }
  36. baseapp.Logger.Infof("[%s] 联网检测: DNS OK=%v, PING OK=%v, TCP OK=%v, HTTP OK=%v, MQTT OK=%v", MODULE_NAME, dnsOK, pingOK, tcpOK, httpOK, mqttOK)
  37. // 2, 检测成功-在线时
  38. if dnsOK && pingOK && tcpOK {
  39. isOnline.Store(true)
  40. offlineStartTs.Store(0)
  41. if isSyncNTPTimeOK.Load() {
  42. t.Reset(interval2)
  43. continue
  44. }
  45. err := SyncNTPTime()
  46. if err == nil {
  47. isSyncNTPTimeOK.Store(true)
  48. baseapp.Logger.Infof("[%s] NTP时间已同步", MODULE_NAME)
  49. t.Reset(interval2)
  50. continue
  51. } else {
  52. baseapp.Logger.Errorf("[%s] 同步NTP时间时有错误发生: %v!!", MODULE_NAME, err)
  53. t.Reset(interval1)
  54. continue
  55. }
  56. }
  57. // 3, 检测失败-离线时
  58. if isOnline.Load() { // 状态由"1"变为"0"
  59. isOnline.Store(false)
  60. offlineStartTs.Store(time.Now().UnixNano()) // 记录离线开始时间
  61. }
  62. if OfflineDuration() >= (time.Duration(60)*time.Second) && !mqttOK {
  63. baseapp.Logger.Warnf("[%s] 检测到网络长时间断开, 将重置4G模块!", MODULE_NAME)
  64. reset4gNetwork()
  65. offlineStartTs.Store(time.Now().UnixNano()) // 重置离线开始时间
  66. }
  67. t.Reset(interval1)
  68. case <-baseapp.IsExit2():
  69. return
  70. } // select end
  71. } // for end
  72. }
  73. // 返回联网状态
  74. func IsInetAvailable() bool {
  75. return isOnline.Load()
  76. }
  77. // 时间是否同步
  78. func IsSyncedNtpTime() bool {
  79. return isSyncNTPTimeOK.Load()
  80. }
  81. // 等待所有成功
  82. func WaitAllOK(timeout time.Duration) bool {
  83. deadline := time.Now().Add(timeout)
  84. tick := 50 * time.Millisecond
  85. for {
  86. if IsInetAvailable() && IsSyncedNtpTime() {
  87. return true
  88. }
  89. remaining := time.Until(deadline)
  90. if remaining <= 0 {
  91. return false
  92. }
  93. sleep := min(tick, remaining)
  94. time.Sleep(sleep)
  95. }
  96. }
  97. // 返回断网时长
  98. func OfflineDuration() time.Duration {
  99. if IsInetAvailable() {
  100. return 0
  101. }
  102. ts := offlineStartTs.Load()
  103. if ts == 0 {
  104. return 0
  105. }
  106. return time.Since(time.Unix(0, ts))
  107. }
  108. // 重启模块联网
  109. func reset4gNetwork() {
  110. modem.ModuleExit()
  111. modem.ModuleInit(true)
  112. }
  113. //export RTU_IsInetAvailable
  114. func RTU_IsInetAvailable() C.int {
  115. if IsInetAvailable() {
  116. return 1
  117. }
  118. return 0
  119. }
  120. //export RTU_IsSyncedNtpTime
  121. func RTU_IsSyncedNtpTime() C.int {
  122. if IsSyncedNtpTime() {
  123. return 1
  124. }
  125. return 0
  126. }