| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // package kserv_http -- встроенный HTTP-сервер
- package kserv_http
- import (
- "embed"
- "fmt"
- "net/http"
- "os"
- "strings"
- "sync"
- "time"
- "github.com/gofiber/fiber/v2"
- "github.com/gofiber/fiber/v2/middleware/compress"
- "github.com/gofiber/fiber/v2/middleware/filesystem"
- "github.com/gofiber/fiber/v2/middleware/monitor"
- . "gitp78su.ipnodns.ru/svi/kern/v2/kc/helpers"
- "gitp78su.ipnodns.ru/svi/kern/v2/kc/local_ctx"
- "gitp78su.ipnodns.ru/svi/kern/v2/kc/safe_bool"
- "gitp78su.ipnodns.ru/svi/kern/v2/krn/kctx"
- . "gitp78su.ipnodns.ru/svi/kern/v2/krn/ktypes"
- )
- const (
- streamName = "kernel_server_http" // Контрольная строка для ожидателя потока
- )
- // kServHttp -- встроенный HTTP-сервер
- type kServHttp struct {
- kCtx IKernelCtx
- ctx ILocalCtx
- log ILogBuf
- strUrl string // URL, на котором слушает HTTP-сервер
- fiberApp *fiber.App
- isWork ISafeBool
- isEnd ISafeBool
- }
- //go:embed static/*
- var embedDirStatic embed.FS
- var (
- kernServHttp *kServHttp
- block sync.Mutex
- )
- // GetKernelServHttp -- возвращает встроенный HTTP-сервер
- func GetKernelServHttp() IKernelServerHttp {
- block.Lock()
- defer block.Unlock()
- if kernServHttp != nil {
- kernServHttp.log.Debug("GetKernelServHttp()")
- return kernServHttp
- }
- ctx := kctx.GetKernelCtx()
- strUrl := os.Getenv("LOCAL_HTTP_URL")
- Hassert(strUrl != "", "GetKernelServHttp(): env LOCAL_HTTP_URL not set")
- confFiber := fiber.Config{
- ServerHeader: ctx.Get("monolitName").Val().(string),
- UnescapePath: true,
- ReadTimeout: time.Second * 15,
- WriteTimeout: time.Second * 15,
- AppName: ctx.Get("monolitName").Val().(string),
- Network: "tcp4",
- EnablePrintRoutes: true,
- }
- sf := &kServHttp{
- kCtx: ctx,
- ctx: local_ctx.NewLocalCtx(ctx.Ctx()),
- strUrl: strUrl,
- fiberApp: fiber.New(confFiber),
- isWork: safe_bool.NewSafeBool(),
- isEnd: safe_bool.NewSafeBool(),
- }
- sf.log = sf.ctx.Log()
- sf.log.Debug("GetKernelServHttp(): first run")
- sf.fiberApp.Use(compress.New(compress.Config{
- Level: compress.LevelBestCompression, // 2
- }))
- sf.fiberApp.Use("/static", filesystem.New(filesystem.Config{
- Root: http.FS(embedDirStatic),
- PathPrefix: "static",
- Browse: true,
- MaxAge: 3600 * 24,
- }))
- sf.fiberApp.Get("/monitor", monitor.New(monitor.Config{Title: ctx.Get("monolitName").Val().(string)}))
- res := sf.kCtx.Wg().Add(streamName)
- res.Hassert("NewKernelServHttp(): in add stream %v", streamName)
- ctx.Set("fiberApp", sf.fiberApp, "kServHttp: internal fiber app")
- kernServHttp = sf
- ctx.Set("kServHttp", kernServHttp, "kServHttp")
- return kernServHttp
- }
- // IsWork -- возвращает признак работы
- func (sf *kServHttp) IsWork() bool {
- return sf.isWork.Get()
- }
- // Log -- возвращает локальный лог
- func (sf *kServHttp) Log() ILogBuf {
- return sf.log
- }
- // Fiber -- возвращает объект веб-приложения fiber
- func (sf *kServHttp) Fiber() *fiber.App {
- return sf.fiberApp
- }
- // Run -- запускает сервер в работу (блокирующий вызов)
- func (sf *kServHttp) Run() {
- if sf.isEnd.Get() {
- return
- }
- if sf.isWork.Get() {
- return
- }
- go sf.close()
- sf.isWork.Set()
- sf.log.Debug("kServHttp.Run(): url='%v'", sf.strUrl)
- lstPort := strings.Split(sf.strUrl, ":")
- strPort := lstPort[len(lstPort)-1]
- strPort = strings.ReplaceAll(strPort, "/", "")
- strPort = strings.ReplaceAll(strPort, `"`, "")
- err := sf.fiberApp.Listen(":" + strPort)
- strOut := fmt.Sprintf("kServHttp.Run(): in listen, err=\n\t%v", err)
- sf.log.Err(strOut)
- sf.kCtx.Cancel()
- sf.isWork.Reset()
- sf.isEnd.Set()
- }
- // Ожидает окончания работы
- func (sf *kServHttp) close() {
- sf.kCtx.Done()
- if !sf.isWork.Get() {
- return
- }
- sf.isWork.Reset()
- sf.isEnd.Set()
- err := sf.fiberApp.Server().Shutdown()
- Assert(err == nil, "kServHttp.close(): in close server, err=\n\t%v", err)
- sf.kCtx.Wg().Done(streamName)
- sf.log.Debug("kServHttp.close(): end")
- }
|