main.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "flag"
  7. "fmt"
  8. "net/http"
  9. "os"
  10. "strconv"
  11. "time"
  12. "rtu_linux_services/servicelib"
  13. "github.com/kardianos/service"
  14. "hnyfkj.com.cn/rtu/linux/baseapp"
  15. "hnyfkj.com.cn/rtu/linux/netmgrd"
  16. "hnyfkj.com.cn/rtu/linux/utils/jsonrpc2"
  17. )
  18. var (
  19. Version = "0.0.0.1"
  20. BuildTime = ""
  21. )
  22. type program struct {
  23. name string
  24. core_server *jsonrpc2.RPCServer
  25. http_server *http.Server
  26. done chan struct{}
  27. }
  28. // Start should not block. Do the actual work async.
  29. func (p *program) Start(s service.Service) error {
  30. baseapp.InitPath()
  31. logCfgFile, err := servicelib.EnsureDefaultLogConfig()
  32. if err != nil {
  33. return err
  34. }
  35. baseapp.InitLogger(logCfgFile)
  36. baseapp.Logger.Infof("App Version: %s, Build Time: %s", Version, BuildTime)
  37. if !netmgrd.ModemInit() {
  38. return errors.New("modem init failed")
  39. }
  40. netmgrd.SetTimeSyncEnabled(false) // 关闭时间同步, 由"timesyncd.service"完成
  41. netmgrd.ModuleInit()
  42. p.core_server, err = jsonrpc2.NewRPCServer(p.name, baseapp.Logger)
  43. if err != nil {
  44. return err
  45. }
  46. methods := make(jsonrpc2.MethodMap)
  47. ////////////////////////////////////////////////////////////
  48. methods["basic.getBuildVer"] = p.getBuildVer /// 获取软件版本
  49. methods["basic.getLogLevel"] = p.getLogLevel /// 获取日志级别
  50. methods["basic.setLogLevel"] = p.setLogLevel /// 设置日志级别
  51. methods["basic.saveLogConf"] = p.saveLogConf /// 保存日志设置
  52. ////////////////////////////////////////////////////////////
  53. methods["core.getModemInfo"] = p.getModemInfo // IMEI、ICCID
  54. methods["core.getNetStatus"] = p.getNetStatus // 联网状态信息
  55. ////////////////////////////////////////////////////////////
  56. err = p.core_server.RegisterMethods(methods)
  57. if err != nil {
  58. return err
  59. }
  60. mux := http.NewServeMux()
  61. mux.Handle("/rpc", p.core_server)
  62. p.http_server = &http.Server{
  63. Addr: "127.0.0.1:7000",
  64. Handler: mux,
  65. }
  66. p.done = make(chan struct{})
  67. go p.run()
  68. return nil
  69. }
  70. // Do work here
  71. func (p *program) run() {
  72. defer close(p.done)
  73. err := p.http_server.ListenAndServe() // 同步阻塞
  74. if err != nil && !errors.Is(err, http.ErrServerClosed) {
  75. baseapp.Logger.Errorf("[%s] start http server error: %v", p.name, err)
  76. return
  77. }
  78. }
  79. // Stop should not block. Return with a few seconds.
  80. func (p *program) Stop(s service.Service) error {
  81. if p.core_server != nil {
  82. p.core_server.Stop()
  83. }
  84. if p.http_server != nil {
  85. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  86. defer cancel()
  87. _ = p.http_server.Shutdown(ctx)
  88. }
  89. if p.done != nil {
  90. <-p.done
  91. }
  92. netmgrd.ModemExit()
  93. baseapp.ExitLogger()
  94. return nil
  95. }
  96. func (p *program) getBuildVer(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  97. result := map[string]string{
  98. "version": Version,
  99. "build_time": BuildTime,
  100. }
  101. return jsonrpc2.BuildResponse(req, result, nil)
  102. }
  103. func (p *program) getLogLevel(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  104. level, _ := baseapp.GetLogLevel()
  105. result := map[string]string{
  106. "log_level": level,
  107. }
  108. return jsonrpc2.BuildResponse(req, result, nil)
  109. }
  110. func (p *program) setLogLevel(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  111. var params map[string]string
  112. if err := json.Unmarshal(req.Params, &params); err != nil {
  113. return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, err.Error())
  114. }
  115. level, ok := params["log_level"]
  116. if !ok || level == "" {
  117. return jsonrpc2.BuildError(req, jsonrpc2.ErrInvalidParams, "missing or empty 'log_level' parameter")
  118. }
  119. err := baseapp.UpdateLogLevel(level)
  120. if err != nil {
  121. return jsonrpc2.BuildError(req, jsonrpc2.ErrInternal, err.Error())
  122. }
  123. return jsonrpc2.BuildResponse(req, "success", nil)
  124. }
  125. func (p *program) saveLogConf(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  126. err := baseapp.SaveLogConfig()
  127. if err != nil {
  128. return jsonrpc2.BuildError(req, jsonrpc2.ErrInternal, err.Error())
  129. }
  130. return jsonrpc2.BuildResponse(req, "success", nil)
  131. }
  132. func (p *program) getModemInfo(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  133. result := map[string]string{
  134. "imei": netmgrd.GetIMEI(),
  135. "iccid": netmgrd.GetSimICCID(),
  136. "rssi": netmgrd.GetRSSI(),
  137. }
  138. return jsonrpc2.BuildResponse(req, result, nil)
  139. }
  140. func (p *program) getNetStatus(ctx context.Context, req *jsonrpc2.Request) *jsonrpc2.Response {
  141. result := map[string]string{
  142. "net_available": strconv.FormatBool(netmgrd.IsInetAvailable()),
  143. "net_type": netmgrd.GetCurrentNetType().String(),
  144. }
  145. return jsonrpc2.BuildResponse(req, result, nil)
  146. }
  147. func main() {
  148. if baseapp.IsArgsParam("-h") {
  149. help()
  150. os.Exit(0)
  151. }
  152. if baseapp.IsArgsParam("-v") {
  153. fmt.Printf("Version: %s, Build Time: %s\n", Version, BuildTime)
  154. os.Exit(0)
  155. }
  156. svcFlag := flag.String("service", "", "Control the system service.")
  157. flag.Parse()
  158. svcConfig := &service.Config{
  159. Name: "yfkj-networkd",
  160. DisplayName: "yfkj-networkd",
  161. Description: "Network connectivity management",
  162. Option: map[string]any{
  163. "Restart": "on-failure",
  164. "RestartSec": "3",
  165. },
  166. }
  167. if baseapp.IsArgsParam("-n") {
  168. fmt.Println(svcConfig.Name + ".service")
  169. os.Exit(0)
  170. }
  171. prg := &program{
  172. name: svcConfig.Name,
  173. }
  174. svc, err := service.New(prg, svcConfig)
  175. if err != nil {
  176. fmt.Printf("%s.service creation failed: %v\n",
  177. svcConfig.Name, err)
  178. os.Exit(1)
  179. }
  180. if len(*svcFlag) != 0 {
  181. err := service.Control(svc, *svcFlag)
  182. if err != nil {
  183. fmt.Printf("%v\n Valid actions: %q\n", err, service.ControlAction)
  184. }
  185. os.Exit(0)
  186. }
  187. if err := svc.Run(); err != nil {
  188. fmt.Printf("%s.service run failed: %v\n",
  189. svcConfig.Name, err)
  190. os.Exit(1)
  191. }
  192. }
  193. func help() {
  194. h := `
  195. -h 显示帮助提示
  196. -n 显示服务名称
  197. -v 当前程序版本
  198. `
  199. fmt.Println(h)
  200. }