package jsruntime import ( "github.com/dop251/goja" "io/ioutil" "log" "net/url" "strings" "sync" "time" ) type JsRuntime struct { MainSrc string UseFileName string UseSrc string Relys Relys TimeoutSec int64 runtime *goja.Runtime mutex sync.Mutex } type Rely struct { Variable string FileName string Src string } type Relys []Rely type RunMode int const ( ModeSync RunMode = 1 //ModeAsync RunMode = 2 ) func NewJsRuntime(mainFileName string, useFileName string, rels Relys, mode RunMode) (*JsRuntime, error) { mainScript, err := ioutil.ReadFile(mainFileName) if err != nil { return nil, err } jr := JsRuntime{ MainSrc: string(mainScript), Relys: rels, UseFileName: useFileName, TimeoutSec: 30, } jr.runtime = goja.New() jr.EnableTimeoutFunc() jr.EnableIntervalFun() jr.EnableRequestFunc() jr.EnableConsoleFun() err = jr.InitJsCode() return &jr, err } func (jr *JsRuntime) InitJsCode() error { for e := range jr.Relys { src, err := ioutil.ReadFile(jr.Relys[e].FileName) if err != nil { return err } jr.Relys[e].Src = string(src) err = jr.RunCode(string(src)) if err != nil { log.Println("initjscode", err) return err } } useSrc, _ := ioutil.ReadFile(jr.UseFileName) jr.UseSrc = string(useSrc) go func() { for { useSrc, _ := ioutil.ReadFile(jr.UseFileName) jr.UseSrc = string(useSrc) time.Sleep(time.Second * 2) } }() return nil } func (jr *JsRuntime) SetVariable(name string, value interface{}) { jr.runtime.Set(name, value) } func (jr *JsRuntime) RunCode(code string) error { _, err := jr.runtime.RunString(code) return err } func (jr *JsRuntime) Render(filePath, href, tplSrc string, cb func(data string)) (err error) { jr.mutex.Lock() defer jr.mutex.Unlock() runtime := jr.runtime timeoutSec := jr.TimeoutSec useSrc := jr.UseSrc mainSrc := jr.MainSrc isLock := true go func() { time.Sleep(time.Duration(timeoutSec) * time.Second) if isLock { runtime.Interrupt("timeout") runtime.ClearInterrupt() } }() defer func() { isLock = false }() _, err = runtime.RunString(useSrc) if err != nil { return } url, err := url.Parse(href) if err != nil { return } url2, err := url.Parse(strings.Replace(filePath, `\`, "/", -1)) if err != nil { return } runtime.Set("GoHtmlSrc", tplSrc) runtime.Set("GoHref", href) runtime.Set("GoQuery", url.Query().Encode()) runtime.Set("GoPath", url2.Path) runtime.Set("GoReturn", func(data string) { cb(data) }) _, err = runtime.RunString(mainSrc) return }