You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

132 lines
2.7 KiB

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
}