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

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
}