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.
147 lines
2.5 KiB
147 lines
2.5 KiB
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
|
|
}
|