netmgrd.go 2.9 KB

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