chromeworker_client/client.go

194 lines
4.1 KiB
Go

package cplient
import (
"context"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/url"
"sync"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// Callback 发送代理连接获取内容后的回调函数
type Callback struct {
label string
hash string
Do func(tid, content string)
}
// Client 客户端
type Client struct {
chromeProxyAddr string
register sync.Map
host string
port string
server *http.Server
listener net.Listener
lock sync.Mutex
}
// Label 区分不同任务类型
type Label struct {
label string
cli *Client
}
// GetHash 根据label获取hash路径
func (l *Label) GetHash(label string) string {
if cb, ok := l.cli.register.Load(label); ok {
return cb.(Callback).hash
}
return ""
}
// GetLabel 根据hash获取路径label
func (l *Label) GetLabel(hash string) string {
if cb, ok := l.cli.register.Load(hash); ok {
return cb.(Callback).label
}
return ""
}
// Open 缓存了Label值. 每次调用少了label传参
func (l *Label) Open(urlstr string) (bodyRes string, ok bool) {
return l.cli.Open(l.label, urlstr)
}
// GetPort Get return port string. default random.
func (cli *Client) GetPort() string {
return cli.port
}
// SetPort Set port string. before client call connect method
func (cli *Client) SetPort(port string) {
cli.port = port
}
// GetHost Get return host string
func (cli *Client) GetHost() string {
return cli.host
}
// SetHost Set host string. default http://127.0.0.1
func (cli *Client) SetHost(host string) {
cli.host = host
}
// Register 注册基础信息
func (cli *Client) Register(label string, callback func(tid, content string)) *Label {
cb := Callback{Do: callback, hash: uuid.New().String()}
if _, ok := cli.register.Load(label); ok {
log.Panic("label: ", label, " is exists")
}
cli.register.Store(label, cb)
cli.register.Store(cb.hash, cb)
l := &Label{label: label, cli: cli}
return l
}
// UnRegister 卸载注册基础信息
func (cli *Client) UnRegister(label string) {
if cb, ok := cli.register.Load(label); ok {
cli.register.Delete(label)
cli.register.Delete(cb.(Callback).hash)
}
}
// Connect 连接初始化回调端口
func (cli *Client) Connect() {
cli.lock.Lock()
defer cli.lock.Unlock()
if cli.server == nil {
listener, err := net.Listen("tcp", ":0")
if err != nil {
panic(err)
}
cli.port = fmt.Sprintf("%d", listener.Addr().(*net.TCPAddr).Port)
router := gin.Default()
router.POST("/:label", func(c *gin.Context) {
label := c.Param("label")
if f, ok := cli.register.Load(label); ok {
callback := f.(Callback)
if tid, ok := c.GetPostForm("taskid"); ok {
content := c.PostForm("content")
callback.Do(tid, content)
}
}
})
cli.server = &http.Server{
Addr: cli.host + ":" + cli.port,
Handler: router,
}
go func() {
err := cli.server.Serve(listener)
if err != nil {
panic(err)
}
}()
} else {
log.Println("client had connected.")
}
// panic(http.Serve(listener, nil))
}
// Disconnect 断开连接
func (cli *Client) Disconnect() {
err := cli.server.Shutdown(context.Background())
if err != nil {
panic(err)
}
}
// Open 请求完url后 调用不同label注册的回调函数
func (cli *Client) Open(label, urlstr string) (bodyRes string, ok bool) {
// urlstr = "https://playerduo.com/api/playerDuo-service-v2/rip113?lang=en&deviceType=browser"
if cli.server == nil {
panic("client is not connect. Client.Connect() ? ")
}
if callback, ok := cli.register.Load(label); ok {
data := url.Values{}
data["url"] = []string{urlstr}
data["callback"] = []string{cli.host + ":" + cli.port + "/" + callback.(Callback).hash}
data["label"] = []string{label}
resp, err := http.DefaultClient.PostForm(cli.chromeProxyAddr+"/task/put", data)
if err != nil {
panic(err)
}
bodyRes, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return string(bodyRes), true
}
log.Printf("label: %s is not exists", label)
return "", false
}
// New 创建Client并初始化
func New(addr string) *Client {
cli := &Client{}
cli.chromeProxyAddr = addr
cli.host = "http://127.0.0.1"
return cli
}