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 }