package comm import ( "crypto/md5" "encoding/json" "fmt" "os" "path" "path/filepath" "strings" "time" "github.com/nats-io/nats.go" "github.com/spf13/viper" ) const ( APPSTATE_RUNNING = "运行中" APPSTATE_INSTALLED = "已安装" ) type App struct { Id string Name string Label string Desc string Icon string IconUrl string Version string Type string ExeFpath string Pwd string Args string RegTime time.Time LastRuningTime time.Time Status string //运行中 } func GetAppId() (string, error) { f, e := os.Executable() if e != nil { return "", e } _, exeName := filepath.Split(f) if strings.Contains(f, "go-build") { fmt.Println() pwd, e := os.Getwd() if e != nil { return "", e } f = path.Join(pwd, exeName) } fmt.Println("app path=>", f) md := md5.Sum([]byte(f)) return fmt.Sprintf("%x", md), nil } func GetAppPathId(fpath string) string { md := md5.Sum([]byte(fpath)) return fmt.Sprintf("%x", md) } func ParseConfigFile(filepath string) (*App, error) { file, err := os.Open(filepath) if err != nil { return nil, err } v := viper.New() v.SetConfigType("yaml") err = v.ReadConfig(file) if err != nil { return nil, err } c := new(App) err = v.Unmarshal(c) return c, err } var _callCancel = func() {} func CancelServeRun() { _callCancel() } func ServerRun(bus *NatsBus) error { cancel := WatchChange(bus) if cancel == nil { return fmt.Errorf("启动App监听失败") } _callCancel = cancel bus.Subscribe("lancher.apps.list", func(msg *nats.Msg) { out := []*App{} nc := bus.GetNatsConn() js, e := nc.JetStream() if e == nil { kv, e := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "lancher-apps"}) if e == nil { out = getApps(kv) } } payload, _ := json.Marshal(out) msg.Respond(payload) }) //启动app bus.Subscribe("lancher.start.*", func(msg *nats.Msg) { //获取AppId fmt.Println("starting=>", msg.Subject) }) return nil } func WatchChange(bus *NatsBus) func() { nc := bus.GetNatsConn() js, e := nc.JetStream() if e != nil { fmt.Println(e) return nil } if e != nil { fmt.Println(e) return nil } kv, e := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "lancher-apps"}) if e != nil { return nil } watch, e := kv.WatchAll() if e != nil { return nil } quiteCh := make(chan int, 1) go func() { for { conti := true select { case <-quiteCh: conti = false default: v := <-watch.Updates() if v != nil { fmt.Println("wathing update=>", v.Key(), v.Bucket(), v.Operation()) } bus.PublishObj("lancher.apps.updated", getApps(kv)) time.Sleep(time.Second) } if !conti { break } } fmt.Println("waching app quited") }() return func() { quiteCh <- 1 } } func getApps(kv nats.KeyValue) []*App { out := []*App{} keys, e := kv.Keys() if e != nil { fmt.Println("keys error=>", e) return out } for _, key := range keys { v, _ := kv.Get(key) if v != nil { app := &App{} e := json.Unmarshal(v.Value(), app) if e == nil { fmt.Println("app=>", *app) out = append(out, app) } else { fmt.Println("Unmarshal errr=>", e) } } } return out }