第一版
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
package libs
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
)
|
||||
|
||||
// Browser 浏览器实例管理器
|
||||
type Browser struct{}
|
||||
|
||||
// BrowserInfo 浏览器实例信息
|
||||
type BrowserInfo struct {
|
||||
Id int
|
||||
Browser *rod.Browser
|
||||
@@ -15,7 +18,7 @@ type BrowserInfo struct {
|
||||
Page *rod.Page
|
||||
}
|
||||
|
||||
// 浏览器指纹数据
|
||||
// Fingerprint 浏览器指纹配置
|
||||
type Fingerprint struct {
|
||||
Viewport []struct {
|
||||
Height int
|
||||
@@ -26,58 +29,61 @@ type Fingerprint struct {
|
||||
}
|
||||
|
||||
var (
|
||||
BrowserPool = make(map[int]*BrowserInfo) // 初始化map
|
||||
poolMutex sync.RWMutex // 添加读写锁保证并发安全
|
||||
browserPool = make(map[int]*BrowserInfo)
|
||||
poolMutex sync.RWMutex
|
||||
)
|
||||
|
||||
var ChromeExample Chrome
|
||||
|
||||
// GetBrowser 获取或创建浏览器实例(线程安全,双重检查锁定)
|
||||
func (*Browser) GetBrowser(id int, params *Fingerprint) *BrowserInfo {
|
||||
poolMutex.RLock()
|
||||
value, ok := BrowserPool[id]
|
||||
value, ok := browserPool[id]
|
||||
poolMutex.RUnlock()
|
||||
|
||||
if ok {
|
||||
return value
|
||||
}
|
||||
|
||||
// 未找到时获取写锁(互斥)
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
// 双检查:避免在等待锁期间其他goroutine已创建
|
||||
if value, ok := BrowserPool[id]; ok {
|
||||
// 双重检查
|
||||
if value, ok := browserPool[id]; ok {
|
||||
return value
|
||||
}
|
||||
|
||||
// 创建新实例(补充CancelFunc)
|
||||
var ChromeExample Chrome
|
||||
browser, url, page := ChromeExample.Create(id, params)
|
||||
var chrome Chrome
|
||||
browser, url, page := chrome.Create(id, params)
|
||||
browserInfo := &BrowserInfo{
|
||||
Id: id,
|
||||
Browser: browser,
|
||||
Url: url,
|
||||
Page: page,
|
||||
}
|
||||
BrowserPool[id] = browserInfo
|
||||
browserPool[id] = browserInfo
|
||||
log.Printf("[浏览器] 创建实例 #%d", id)
|
||||
return browserInfo
|
||||
}
|
||||
|
||||
func (*Browser) GetAllBrowser() map[int]*BrowserInfo {
|
||||
return BrowserPool
|
||||
}
|
||||
|
||||
func (*Browser) CancelAllBrowser() {
|
||||
for _, v := range BrowserPool {
|
||||
// CloseAll 关闭所有浏览器实例
|
||||
func (*Browser) CloseAll() {
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
for id, v := range browserPool {
|
||||
v.Browser.MustClose()
|
||||
delete(browserPool, id)
|
||||
}
|
||||
log.Println("[浏览器] 已关闭所有实例")
|
||||
}
|
||||
|
||||
func (*Browser) CancelBrowser(id int) {
|
||||
browserInfo := BrowserPool[id]
|
||||
if browserInfo == nil {
|
||||
// Close 关闭指定浏览器实例
|
||||
func (*Browser) Close(id int) {
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
info, ok := browserPool[id]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
browserInfo.Browser.MustClose()
|
||||
delete(BrowserPool, id)
|
||||
info.Browser.MustClose()
|
||||
delete(browserPool, id)
|
||||
log.Printf("[浏览器] 已关闭实例 #%d", id)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user