http/chrome.go
2025-07-22 20:45:03 +08:00

83 lines
1.9 KiB
Go

package http
import (
"runtime"
"sync"
"apigo.cc/gojs"
"apigo.cc/gojs/goja"
"github.com/go-rod/rod"
"github.com/go-rod/rod/lib/launcher"
"github.com/ssgo/u"
)
type Chrome struct {
id string
launcher *launcher.Launcher
browser *rod.Browser
}
var chromes = map[string]*Chrome{}
var chromesLock sync.Mutex
func (ch *Chrome) Close(vm *goja.Runtime) {
logger := gojs.GetLogger(vm)
if ch.browser != nil {
logger.Info("关闭本地 Chrome 浏览器", "id", ch.id)
ch.browser.Close()
ch.browser = nil
}
if ch.launcher != nil {
ch.launcher.Cleanup()
ch.launcher = nil
}
chromesLock.Lock()
delete(chromes, ch.id)
chromesLock.Unlock()
}
func CloseAllChrome(vm *goja.Runtime) {
n := len(chromes)
if n > 0 {
for _, ch := range chromes {
ch.Close(vm)
}
logger := gojs.GetLogger(vm)
logger.Info("关闭所有 Chrome 浏览器", "count", n)
}
}
func StartChrome(showWindow *bool, vm *goja.Runtime) (*Chrome, error) {
logger := gojs.GetLogger(vm)
ch := &Chrome{}
ch.id = u.UniqueId()
ch.browser = rod.New()
if localBrowserPath, hasLocalBrowser := launcher.LookPath(); hasLocalBrowser {
ch.launcher = launcher.New().Bin(localBrowserPath).Headless(!u.Bool(showWindow)).Set("no-sandbox").Set("disable-gpu").Set("disable-dev-shm-usage").Set("single-process")
switch runtime.GOOS {
case "linux":
ch.launcher.Set("disable-setuid-sandbox")
case "windows":
ch.launcher.Set("disable-features=RendererCodeIntegrity")
}
localChromeURL, err := ch.launcher.Launch()
if err != nil {
ch.Close(vm)
return nil, gojs.Err(err)
}
logger.Info("启动本地 Chrome 浏览器", "id", ch.id, "url", localChromeURL, "path", localBrowserPath)
ch.browser.ControlURL(localChromeURL)
}
if err := ch.browser.Connect(); err != nil {
ch.Close(vm)
return nil, gojs.Err(err)
}
chromesLock.Lock()
chromes[ch.id] = ch
chromesLock.Unlock()
return ch, nil
}