package jsruntime import ( "encoding/json" "git.ouxuan.net/hasaki-service/hasaki-sdk/hskhttpdo" "github.com/dop251/goja" "github.com/dop251/goja_nodejs/console" "github.com/dop251/goja_nodejs/eventloop" "github.com/dop251/goja_nodejs/require" "io/ioutil" "time" ) type JsRuntime struct { MainSrc string UseSrc string Relys Relys TimeoutSec int64 runtime *goja.Runtime registry *require.Registry requireModule *require.RequireModule loop *eventloop.EventLoop } type Rely struct { Variable string FileName string } type Relys []Rely func NewJsRuntime(mainFileName string, useFileName string, rels Relys) (*JsRuntime, error) { jr := JsRuntime{ Relys: rels, TimeoutSec: 8, } mainScript, err := ioutil.ReadFile(mainFileName) if err != nil { return nil, err } jr.MainSrc = string(mainScript) jr.registry = new(require.Registry) // this can be shared by multiple runtimes jr.loop = eventloop.NewEventLoop() jr.loop.Run(func(r *goja.Runtime) { jr.runtime = r }) jr.requireModule = jr.registry.Enable(jr.runtime) console.Enable(jr.runtime) jr.runtime.Set("GoVueUse", func(v interface{}) { jr.runtime.Set("GoVueUseCall", v) }) jr.setAjax() for e := range rels { v, err := jr.requireModule.Require(rels[e].FileName) if err != nil { return nil, err } jr.runtime.Set(rels[e].Variable, v) } go func() { for { useSrc, _ := ioutil.ReadFile(useFileName) jr.UseSrc = string(useSrc) time.Sleep(time.Second * 2) } }() return &jr, nil } func (jr *JsRuntime) setAjax() { jr.runtime.Set("GO_AJAX", func(call goja.FunctionCall) string { m := call.Argument(0) url := call.Argument(1) data := call.Argument(3) res, err := hskhttpdo.HttpDo{ Url: url.String(), Raw: []byte(data.String()), }.Request(m.String()) r := map[string]string{ "code": "200", "data": string(res), } if err != nil { r["code"] = "502" } rs, _ := json.Marshal(r) return string(rs) }) } func (jr *JsRuntime) SetVariable(name string, value interface{}) { jr.runtime.Set(name, value) } func (jr *JsRuntime) Render(href, tplSrc string) string { jr.registry.Lock() isLock := true go func() { time.Sleep(time.Duration(jr.TimeoutSec) * time.Second) if isLock { jr.runtime.Interrupt("timeout") } }() defer func() { isLock = false jr.registry.Unlock() }() _, err := jr.runtime.RunString(jr.UseSrc) if err != nil { return err.Error() } jr.runtime.Set("HTML_SRC", tplSrc) jr.runtime.Set("SELF_HREF", href) result := "" jr.runtime.Set("HTML_OUT", func(data string) { result = data }) _, err = jr.runtime.RunString(jr.MainSrc) if err != nil { return err.Error() } return result }