main.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package main
  2. import (
  3. "context"
  4. "errors"
  5. "flag"
  6. "fmt"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "rtu_linux_services/servicelib"
  11. "time"
  12. "github.com/kardianos/service"
  13. "hnyfkj.com.cn/rtu/linux/baseapp"
  14. "hnyfkj.com.cn/rtu/linux/utils/jsonrpc2"
  15. )
  16. var (
  17. Version = "0.0.0.1"
  18. BuildTime = ""
  19. )
  20. const (
  21. network = "tcp" // http -> tcp
  22. listenAddr = "127.0.0.1:7004"
  23. )
  24. var userAppPkgDir = "" // 存储上传的用户应用安装包信息
  25. type program struct {
  26. name string
  27. core_server *jsonrpc2.RPCServer
  28. http_server *http.Server
  29. }
  30. // Start should not block. Do the actual work async.
  31. func (p *program) Start(s service.Service) error {
  32. logCfgFile, err := servicelib.EnsureDefaultLogConfig()
  33. if err != nil {
  34. return err
  35. }
  36. baseapp.InitLogger(logCfgFile)
  37. baseapp.Logger.Infof("[%s] 开始运行, 程序版本: %s, 构建时间: %s", p.name, Version, BuildTime)
  38. userAppPkgDir = filepath.Join(baseapp.EXEC_DIR, "userapp")
  39. if err := os.MkdirAll(userAppPkgDir, 0755); err != nil {
  40. return err
  41. }
  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. _getBuildVer := servicelib.MakeGetBuildVer(
  49. Version, BuildTime)
  50. methods["basic.getBuildVer"] = _getBuildVer // 获取软件版本
  51. _getLogLevel := servicelib.GetLogLevel
  52. methods["basic.getLogLevel"] = _getLogLevel // 获取日志级别
  53. _setLogLevel := servicelib.SetLogLevel
  54. methods["basic.setLogLevel"] = _setLogLevel // 设置日志级别
  55. _saveLogConf := servicelib.SaveLogConf
  56. methods["basic.saveLogConf"] = _saveLogConf // 保存日志设置
  57. //////////////////////////////////////////////////////////
  58. methods["core.package.import"] = pkgImport ///// 导入安装包
  59. methods["core.package.remove"] = pkgRemove ///// 删除安装包
  60. //////////////////////////////////////////////////////////
  61. methods["core.app.install"] = appInstall //安装用户应用
  62. methods["core.app.uninstall"] = appUninstall //卸载当前应用
  63. //////////////////////////////////////////////////////////
  64. methods["core.getInstallInfo"] = getInstallInfo // 安装信息
  65. err = p.core_server.RegisterMethods(methods)
  66. if err != nil {
  67. return err
  68. }
  69. mux := http.NewServeMux()
  70. mux.Handle("/rpc", p.core_server)
  71. p.http_server = &http.Server{
  72. Addr: listenAddr,
  73. Handler: mux,
  74. }
  75. go p.run()
  76. return nil
  77. }
  78. // Do work here
  79. func (p *program) run() {
  80. baseapp.Logger.Infof(
  81. "[%s] Http server starting on %s...",
  82. p.name,
  83. p.http_server.Addr,
  84. )
  85. err := p.http_server.ListenAndServe() // 同步阻塞
  86. if err != nil && !errors.Is(err, http.ErrServerClosed) {
  87. baseapp.Logger.Errorf("[%s] Start http server error: %v!!", p.name, err)
  88. return
  89. }
  90. }
  91. // Stop should not block. Return with a few seconds.
  92. func (p *program) Stop(s service.Service) error {
  93. if p.core_server != nil {
  94. p.core_server.Stop()
  95. }
  96. if p.http_server != nil {
  97. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  98. defer cancel()
  99. _ = p.http_server.Shutdown(ctx)
  100. }
  101. baseapp.Logger.Infof("[%s] 程序退出", p.name)
  102. baseapp.ExitLogger()
  103. return nil
  104. }
  105. func main() {
  106. baseapp.SetOptDirs(true, false, false, false)
  107. baseapp.InitPath()
  108. svcFlag := flag.String("service", "", "Control the yfkj-app-install service.")
  109. flag.Parse()
  110. svcConfig := &service.Config{
  111. Name: "yfkj-app-install",
  112. DisplayName: "yfkj-app-install",
  113. Description: "Yunfei User Application Installation And Uninstallation",
  114. Option: map[string]any{
  115. "Restart": "always", // 无条件重启
  116. },
  117. }
  118. servicelib.WriteVersionFile(baseapp.EXEC_DIR, Version) //-> for 升级
  119. prg := &program{
  120. name: "AppInstaller",
  121. }
  122. svc, err := service.New(prg, svcConfig)
  123. if err != nil {
  124. fmt.Printf("%s.service creation failed: %v\n",
  125. svcConfig.Name, err)
  126. os.Exit(1)
  127. }
  128. if len(*svcFlag) != 0 {
  129. err := service.Control(svc, *svcFlag)
  130. if err != nil {
  131. fmt.Printf("%v\n Valid actions: %q\n", err, service.ControlAction)
  132. }
  133. os.Exit(0)
  134. }
  135. if servicelib.IsAddrInUse(network, listenAddr) { // 查询端口占用,避免运行多份实例
  136. fmt.Printf(
  137. "%s.service start failed: listen addr %s already in use\n",
  138. svcConfig.Name, listenAddr,
  139. )
  140. os.Exit(1)
  141. }
  142. if err := svc.Run(); err != nil {
  143. fmt.Printf("%s.service run failed: %v\n",
  144. svcConfig.Name, err)
  145. os.Exit(1)
  146. }
  147. }