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.

232 lines
5.3 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package govue
  2. //go-bindata-assetfs --pkg=govue govue-runtime/...
  3. import (
  4. "fmt"
  5. "git.ouxuan.net/3136352472/go-service-template/jsruntime"
  6. "git.ouxuan.net/3136352472/go-service-template/pool"
  7. "github.com/elazarl/go-bindata-assetfs"
  8. "io/ioutil"
  9. "log"
  10. "net/http"
  11. "os"
  12. "path/filepath"
  13. "strings"
  14. "time"
  15. )
  16. type GoVue struct {
  17. StaticPath string
  18. UseJsPath string
  19. ErrorPage404 string
  20. Resources *assetfs.AssetFS
  21. IsDebugMode bool
  22. jsRuntimePool *pool.JsRuntimePool
  23. }
  24. func NewGoVueDefaultConfig(debug bool) (gv *GoVue, err error) {
  25. gv = &GoVue{
  26. Resources: assetFS(),
  27. IsDebugMode: debug,
  28. }
  29. err = gv.initRender(debug)
  30. return
  31. }
  32. func NewGoVue(useJsPath string, staticPath string, debug bool) (gv *GoVue, err error) {
  33. gv = &GoVue{
  34. StaticPath: staticPath,
  35. UseJsPath: useJsPath,
  36. Resources: assetFS(),
  37. IsDebugMode: debug,
  38. }
  39. err = gv.initRender(debug)
  40. return
  41. }
  42. func (gv *GoVue) SetErrorPage404(page string) {
  43. gv.ErrorPage404 = page
  44. }
  45. func SetPoolConfig(config pool.Config) {
  46. pool.DefaultConfig = config
  47. }
  48. func (gv *GoVue) initRender(debug bool) (err error) {
  49. if gv.StaticPath == "" {
  50. gv.StaticPath = filepath.Join(getSelfFilePath(), "static")
  51. }
  52. if gv.UseJsPath == "" {
  53. gv.UseJsPath = filepath.Join(gv.StaticPath, "use.js")
  54. }
  55. govueScriptFile := "govue-release.js"
  56. if gv.IsDebugMode {
  57. govueScriptFile = "govue-dev.js"
  58. }
  59. polyfill, err := ioutil.ReadFile(filepath.Join("govue", "govue-runtime", "polyfill.js"))
  60. if err != nil {
  61. return
  62. }
  63. headerScript, err := ioutil.ReadFile(filepath.Join("govue", "govue-runtime", "header.js"))
  64. if err != nil {
  65. return
  66. }
  67. govueScript, err := ioutil.ReadFile(filepath.Join("govue", "govue-runtime", govueScriptFile))
  68. if err != nil {
  69. return
  70. }
  71. mainScript, err := ioutil.ReadFile(filepath.Join("govue", "govue-runtime", "runtime.js"))
  72. if err != nil {
  73. return
  74. }
  75. //polyfill, err := gv.Resources.Asset(filepath.Join("govue-runtime", "polyfill.js"))
  76. //if err != nil {
  77. // return
  78. //}
  79. //
  80. //headerScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", "header.js"))
  81. //if err != nil {
  82. // return
  83. //}
  84. //
  85. //govueScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", govueScriptFile))
  86. //if err != nil {
  87. // return
  88. //}
  89. //
  90. //mainScript, err := gv.Resources.Asset(filepath.Join("govue-runtime", "runtime.js"))
  91. //if err != nil {
  92. // return
  93. //}
  94. gv.jsRuntimePool = pool.NewJsRuntimePool(string(mainScript), gv.UseJsPath, gv.StaticPath, jsruntime.Relys{
  95. jsruntime.Rely{
  96. Src: string(polyfill),
  97. },
  98. jsruntime.Rely{
  99. Src: string(headerScript),
  100. },
  101. jsruntime.Rely{
  102. Src: string(govueScript),
  103. },
  104. }, jsruntime.ModeSync, debug)
  105. return
  106. }
  107. func (gv *GoVue) PoolLog() {
  108. gv.jsRuntimePool.Log()
  109. }
  110. func (gv *GoVue) StartPoolLog() {
  111. go func() {
  112. defer func() {
  113. recover()
  114. log.Println("统计协程异常")
  115. }()
  116. lastidle := 0
  117. lastactive := 0
  118. for {
  119. all, idle, active := gv.jsRuntimePool.NumInfo()
  120. if idle != lastidle || active != lastactive {
  121. fmt.Println("渲染协程数量变动变动:所有:", all, "空闲:", idle, "活动:", active)
  122. }
  123. lastidle = idle
  124. lastactive = active
  125. time.Sleep(time.Second)
  126. }
  127. }()
  128. }
  129. func (gv *GoVue) LoadStaticResources(request *http.Request, goExtDataS ...interface{}) (result []byte, err error) {
  130. var staticDir string
  131. var filePath = request.URL.Path
  132. if gv.StaticPath == "" {
  133. staticDir = filepath.Join(getSelfFilePath(), "static")
  134. } else {
  135. staticDir = gv.StaticPath
  136. }
  137. filePath = filepath.Join(staticDir, filePath)
  138. fi, err := os.Stat(filePath)
  139. if err == nil {
  140. if fi.IsDir() {
  141. defaultPath := []string{"index.vue", "index.html"}
  142. for e := range defaultPath {
  143. path := filepath.Join(filePath, defaultPath[e])
  144. _, err := os.Stat(path)
  145. if err == nil {
  146. filePath = path
  147. break
  148. }
  149. }
  150. }
  151. } else {
  152. if filepath.Ext(filePath) == ".html" {
  153. split := strings.Split(filePath, ".")
  154. split[len(split)-1] = "vue"
  155. vuePath := strings.Join(split, ".")
  156. _, err := os.Stat(vuePath)
  157. if err == nil {
  158. filePath = vuePath
  159. }
  160. }
  161. }
  162. result, err = ioutil.ReadFile(filePath)
  163. if err != nil {
  164. return gv.renderErrPage(404, request, goExtDataS...)
  165. }
  166. if filepath.Ext(filePath) != ".html" && filepath.Ext(filePath) != ".vue" {
  167. return
  168. }
  169. var goExtData interface{}
  170. if len(goExtDataS) > 0 {
  171. goExtData = goExtDataS[0]
  172. }
  173. err = gv.jsRuntimePool.JsRuntimeCall(func(jr *jsruntime.JsRuntime) {
  174. if filepath.Ext(filePath) == ".vue" {
  175. jr.SetVariable("IS_VUE_SSR", true)
  176. } else {
  177. jr.SetVariable("IS_VUE_SSR", false)
  178. }
  179. err = jr.Render(filePath, fmt.Sprintf("http://%s%s", request.Host, request.RequestURI), string(result), goExtData, func(data string) {
  180. result = []byte(data)
  181. })
  182. if err != nil {
  183. result = []byte(err.Error())
  184. }
  185. })
  186. return
  187. }
  188. func (gv *GoVue) renderErrPage(errCode int, request *http.Request, goExtDataS ...interface{}) (result []byte, err error) {
  189. filePath := gv.ErrorPage404
  190. if filePath == "" {
  191. return []byte("页面不存在"), err
  192. }
  193. result, _ = ioutil.ReadFile(filePath)
  194. var goExtData interface{}
  195. if len(goExtDataS) > 0 {
  196. goExtData = goExtDataS[0]
  197. }
  198. err = gv.jsRuntimePool.JsRuntimeCall(func(jr *jsruntime.JsRuntime) {
  199. err = jr.Render(filePath, fmt.Sprintf("http://%s%s", request.Host, request.RequestURI), string(result), goExtData, func(data string) {
  200. result = []byte(data)
  201. })
  202. })
  203. return
  204. }