|
|
package govue2
//go-bindata-assetfs --pkg=govue govue-runtime/...
import ( "fmt" "git.ouxuan.net/3136352472/go-service-template/jsruntime" "git.ouxuan.net/3136352472/go-service-template/pool" "github.com/elazarl/go-bindata-assetfs" "io/ioutil" "log" "net/http" "os" "path/filepath" "time" )
type GoVue struct { StaticPath string UseJsPath string ErrorPage404 string Resources *assetfs.AssetFS IsDebugMode bool jsRuntimePool *pool.JsRuntimePool CacheSec int64 }
func NewGoVueDefaultConfig(debug bool) (gv *GoVue, err error) {
gv = &GoVue{ Resources: assetFS(), IsDebugMode: debug, } err = gv.initRender(debug) return }
func NewGoVue(useJsPath string, staticPath string, debug bool) (gv *GoVue, err error) { gv = &GoVue{ StaticPath: staticPath, UseJsPath: useJsPath, Resources: assetFS(), IsDebugMode: debug, } err = gv.initRender(debug) return }
func (gv *GoVue) SetCacheSec(cacheSec int64) { gv.CacheSec = cacheSec }
func (gv *GoVue) SetErrorPage404(page string) { gv.ErrorPage404 = page }
func SetPoolConfig(config pool.Config) { pool.DefaultConfig = config }
func (gv *GoVue) initRender(debug bool) (err error) { if gv.StaticPath == "" { gv.StaticPath = filepath.Join(getSelfFilePath(), "static") }
if gv.UseJsPath == "" { gv.UseJsPath = filepath.Join(gv.StaticPath, "use.js") }
headerScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", "header.js")) if err != nil { return }
polyfill, err := gv.Resources.Asset(filepath.Join("govue-runtime", "polyfill.js")) if err != nil { return }
mainScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", "runtime.js")) if err != nil { return }
govueScriptFile := "govue.js" govueScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", govueScriptFile)) if err != nil { return }
gv.jsRuntimePool = pool.NewJsRuntimePool(string(mainScript), gv.UseJsPath, gv.StaticPath, jsruntime.Relys{ jsruntime.Rely{ Src: string(headerScript), }, jsruntime.Rely{ Src: string(polyfill), }, jsruntime.Rely{ Src: string(govueScript), }, }, jsruntime.ModeSync, debug) return }
func (gv *GoVue) PoolLog() { gv.jsRuntimePool.Log() }
func (gv *GoVue) StartPoolLog() { go func() { defer func() { recover() log.Println("统计协程异常") }() lastidle := 0 lastactive := 0 for { all, idle, active := gv.jsRuntimePool.NumInfo() if idle != lastidle || active != lastactive { fmt.Println("渲染协程数量变动变动:所有:", all, "空闲:", idle, "活动:", active) } lastidle = idle lastactive = active time.Sleep(time.Second) } }() }
func (gv *GoVue) LoadStaticResources(request *http.Request, goExtDataS ...interface{}) (result []byte, err error) { cacheKey := fmt.Sprintf("%s|%s", request.URL.Path, request.URL.RawQuery) if gv.CacheSec > 0 { html := GetCache(cacheKey) if html != "" { //log.Println("加载缓存")
return []byte(html), nil } }
//log.Println("非缓存", cacheKey)
var staticDir string var filePath = request.URL.Path if gv.StaticPath == "" { staticDir = filepath.Join(getSelfFilePath(), "static") } else { staticDir = gv.StaticPath }
filePath = filepath.Join(staticDir, filePath)
fi, err := os.Stat(filePath) if err == nil { if fi.IsDir() { defaultPath := []string{"index.html"} for e := range defaultPath { path := filepath.Join(filePath, defaultPath[e]) _, err := os.Stat(path) if err == nil { filePath = path break } } } }
result, err = ioutil.ReadFile(filePath) if err != nil { result, err = gv.renderErrPage(404, request, goExtDataS...) if gv.CacheSec > 0 { SetCache(cacheKey, string(result), gv.CacheSec) } return } if filepath.Ext(filePath) != ".html" { return }
err = gv.jsRuntimePool.JsRuntimeCall(func(jr *jsruntime.JsRuntime) {
err = jr.Render(filePath, fmt.Sprintf("http://%s%s", request.Host, request.RequestURI), string(result), nil, func(data string) { result = []byte(data) if gv.CacheSec > 0 { SetCache(cacheKey, string(result), gv.CacheSec) } }) if err != nil { result = []byte(err.Error()) } })
return }
func (gv *GoVue) renderErrPage(errCode int, request *http.Request, goExtDataS ...interface{}) (result []byte, err error) { filePath := gv.ErrorPage404 if filePath == "" { return []byte("页面不存在"), err } result, _ = ioutil.ReadFile(filePath)
var goExtData interface{} if len(goExtDataS) > 0 { goExtData = goExtDataS[0] } err = gv.jsRuntimePool.JsRuntimeCall(func(jr *jsruntime.JsRuntime) { err = jr.Render(filePath, fmt.Sprintf("http://%s%s", request.Host, request.RequestURI), string(result), goExtData, func(data string) { result = []byte(data) }) }) return }
|