kernel_serv_http.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // package kernel_serv_http -- встроенный HTTP-сервер
  2. package kernel_serv_http
  3. import (
  4. "embed"
  5. "log"
  6. "net/http"
  7. "os"
  8. "sync"
  9. "time"
  10. "github.com/gofiber/fiber/v2"
  11. "github.com/gofiber/fiber/v2/middleware/compress"
  12. "github.com/gofiber/fiber/v2/middleware/filesystem"
  13. "github.com/gofiber/fiber/v2/middleware/monitor"
  14. "wartank/kernel/internal/safe_bool"
  15. . "wartank/kernel/kernel_types"
  16. . "wartank/pkg/helpers"
  17. )
  18. const (
  19. streamName = "kernel_server_http" // Контрольная строка для ожидателя потока
  20. )
  21. // kernelServHttp -- встроенный HTTP-сервер
  22. type kernelServHttp struct {
  23. ctx ИЯдроКонтекст
  24. strPort string // Порт ,на котором слушает HTTP-сервер
  25. fiberApp *fiber.App
  26. isWork ИБезопБул
  27. block sync.Mutex
  28. }
  29. //go:embed static/*
  30. var embedDirStatic embed.FS
  31. var (
  32. kernServHttp *kernelServHttp
  33. block sync.Mutex
  34. )
  35. // GetKernelServHttp -- возвращает встроенный HTTP-сервер
  36. func GetKernelServHttp(ctx ИЯдроКонтекст) ИЯдроСерверВеб {
  37. log.Println("NewKernelServHttp()")
  38. block.Lock()
  39. defer block.Unlock()
  40. if kernServHttp != nil {
  41. return kernServHttp
  42. }
  43. strPort := os.Getenv("SERVER_HTTP_PORT")
  44. Паника(strPort != "", "NewKernelServHttp(): env SERVER_HTTP_PORT not set")
  45. confFiber := fiber.Config{
  46. ServerHeader: "KernelServerWeb",
  47. UnescapePath: true,
  48. ReadTimeout: time.Second * 15,
  49. WriteTimeout: time.Second * 15,
  50. AppName: "KernelServerWeb",
  51. Network: "tcp4",
  52. EnablePrintRoutes: true,
  53. }
  54. sf := &kernelServHttp{
  55. ctx: ctx,
  56. strPort: strPort,
  57. fiberApp: fiber.New(confFiber),
  58. isWork: safe_bool.НовБезопБул_(),
  59. }
  60. sf.fiberApp.Use(compress.New(compress.Config{
  61. Level: compress.LevelBestCompression, // 2
  62. }))
  63. sf.fiberApp.Use("/static", filesystem.New(filesystem.Config{
  64. Root: http.FS(embedDirStatic),
  65. PathPrefix: "static",
  66. Browse: true,
  67. MaxAge: 3600 * 24,
  68. }))
  69. sf.fiberApp.Get("/monitor", monitor.New(monitor.Config{Title: "KernelServerWeb"}))
  70. err := sf.ctx.Оп().Add(streamName)
  71. Паника(err == nil, "NewKernelServHttp(): in add stream %v, err=\n\t%v", streamName, err)
  72. ctx.Уст("fiberApp", sf.fiberApp)
  73. kernServHttp = sf
  74. ctx.Уст("kernServHttp", kernServHttp)
  75. return kernServHttp
  76. }
  77. // Fiber -- возвращает объект веб-приложения fiber
  78. func (sf *kernelServHttp) Fiber() *fiber.App {
  79. return sf.fiberApp
  80. }
  81. // Run -- запускает сервер в работу (блокирующий вызов)
  82. func (sf *kernelServHttp) Run() {
  83. go sf.close()
  84. sf.isWork.Уст()
  85. err := sf.fiberApp.Listen(":" + sf.strPort)
  86. if err != nil {
  87. log.Printf("kernelServHttp.Run(): in listen, err=\n\t%v\n", err)
  88. sf.ctx.Отменить()
  89. }
  90. }
  91. // Ожидает окончания работы
  92. func (sf *kernelServHttp) close() {
  93. <-sf.ctx.Конт().Done()
  94. sf.block.Lock()
  95. defer sf.block.Unlock()
  96. if !sf.isWork.Получ() {
  97. return
  98. }
  99. sf.isWork.Сброс()
  100. err := sf.fiberApp.Server().Shutdown()
  101. Провер(err == nil, "kernelServHttp.close(): in close server, err=\n\t%v", err)
  102. sf.ctx.Оп().Done(streamName)
  103. log.Println("kernelServHttp.close(): end")
  104. }