This commit is contained in:
parent
e20ca6aab0
commit
4b9085fe95
@ -31,6 +31,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pool := pools.NewProxyPool(cfg.Proxy.Subscribes)
|
pool := pools.NewProxyPool(cfg.Proxy.Subscribes)
|
||||||
|
|
||||||
|
go pool.CronUpdate(_ctx, cfg.Proxy.Interval) //定时更新代理
|
||||||
|
|
||||||
pusherCtl := pusher.NewController(_ctx, db)
|
pusherCtl := pusher.NewController(_ctx, db)
|
||||||
ch := make(chan model.PushMsg, 30)
|
ch := make(chan model.PushMsg, 30)
|
||||||
pusherCtl.Consume(ch)
|
pusherCtl.Consume(ch)
|
||||||
@ -45,6 +48,7 @@ func main() {
|
|||||||
|
|
||||||
server.NewWatcherController(watcherCtl).RegistryRouter(api)
|
server.NewWatcherController(watcherCtl).RegistryRouter(api)
|
||||||
server.NewPusherSvcController(pusherCtl).RegistryRouter(api)
|
server.NewPusherSvcController(pusherCtl).RegistryRouter(api)
|
||||||
|
server.NewProxySvc(pool).RegistryRouter(api)
|
||||||
|
|
||||||
if err = r.Listen(":2280"); err != nil {
|
if err = r.Listen(":2280"); err != nil {
|
||||||
glog.Warningf("server over: %v", err)
|
glog.Warningf("server over: %v", err)
|
||||||
|
@ -13,7 +13,7 @@ type Product struct {
|
|||||||
UpdateErr bool `json:"updateErr"` //更新出错了
|
UpdateErr bool `json:"updateErr"` //更新出错了
|
||||||
|
|
||||||
Uid string `json:"uid" gorm:"index:,unique"`
|
Uid string `json:"uid" gorm:"index:,unique"`
|
||||||
Pid string `json:"pid" gorm:"index"` //产品编号
|
Pid string `json:"pid" gorm:"index:,not null"` //产品编号
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Brand string `json:"brand"`
|
Brand string `json:"brand"`
|
||||||
Website WebsiteType `json:"website"` //是什么网站
|
Website WebsiteType `json:"website"` //是什么网站
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type ProxyOption struct {
|
type ProxyOption struct {
|
||||||
Subscribes []string `yaml:"subscribes"`
|
Subscribes []string `yaml:"subscribes"`
|
||||||
|
Interval time.Duration `yaml:"interval"`
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,9 @@ import (
|
|||||||
|
|
||||||
type ProxyPool struct {
|
type ProxyPool struct {
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
proxys proxy.ProxyList
|
proxies proxy.ProxyList
|
||||||
subscribes []string //订阅url
|
subscribes []string //订阅url
|
||||||
|
updated time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxyPool(subscribes []string) *ProxyPool {
|
func NewProxyPool(subscribes []string) *ProxyPool {
|
||||||
@ -26,9 +27,13 @@ func NewProxyPool(subscribes []string) *ProxyPool {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ProxyPool) Status() (proxy.ProxyList, time.Time) {
|
||||||
|
return p.proxies, p.updated
|
||||||
|
}
|
||||||
|
|
||||||
// Update 更新代理池
|
// Update 更新代理池
|
||||||
func (p *ProxyPool) Update() {
|
func (p *ProxyPool) Update() {
|
||||||
var list = make(proxy.ProxyList, 0, len(p.proxys))
|
var list = make(proxy.ProxyList, 0, len(p.proxies))
|
||||||
for _, url := range p.subscribes {
|
for _, url := range p.subscribes {
|
||||||
subscribeGetter, err := getter.NewSubscribe(tool.Options{"url": url})
|
subscribeGetter, err := getter.NewSubscribe(tool.Options{"url": url})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -40,12 +45,16 @@ func (p *ProxyPool) Update() {
|
|||||||
glog.Infof("代理源共 %d 个: %v", len(p.subscribes), p.subscribes)
|
glog.Infof("代理源共 %d 个: %v", len(p.subscribes), p.subscribes)
|
||||||
glog.Infof("获取代理共 %d 个", len(list))
|
glog.Infof("获取代理共 %d 个", len(list))
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
p.proxys = list
|
p.proxies = list
|
||||||
p.m.Unlock()
|
p.m.Unlock()
|
||||||
|
p.updated = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CronUpdate 定时更新
|
// CronUpdate 定时更新
|
||||||
func (p *ProxyPool) CronUpdate(ctx context.Context, interval time.Duration) {
|
func (p *ProxyPool) CronUpdate(ctx context.Context, interval time.Duration) {
|
||||||
|
if interval == 0 {
|
||||||
|
interval = time.Minute * 30
|
||||||
|
}
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for {
|
for {
|
||||||
@ -61,12 +70,12 @@ func (p *ProxyPool) CronUpdate(ctx context.Context, interval time.Duration) {
|
|||||||
// RandomIterator 获取随机代理的迭代器
|
// RandomIterator 获取随机代理的迭代器
|
||||||
func (p *ProxyPool) RandomIterator() func() proxy.Proxy {
|
func (p *ProxyPool) RandomIterator() func() proxy.Proxy {
|
||||||
return func() (proxy proxy.Proxy) {
|
return func() (proxy proxy.Proxy) {
|
||||||
if len(p.proxys) == 0 {
|
if len(p.proxies) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
p.m.Lock()
|
p.m.Lock()
|
||||||
defer p.m.Unlock()
|
defer p.m.Unlock()
|
||||||
curIndex := rand.Intn(len(p.proxys))
|
curIndex := rand.Intn(len(p.proxies))
|
||||||
return p.proxys[curIndex]
|
return p.proxies[curIndex]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ func (c *CoachOutlet) Restart() {
|
|||||||
c.Cancel()
|
c.Cancel()
|
||||||
go c.Watch()
|
go c.Watch()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CoachOutlet) Watch() {
|
func (c *CoachOutlet) Watch() {
|
||||||
c.ctx, c.cancel = context.WithCancel(c.fCtx)
|
c.ctx, c.cancel = context.WithCancel(c.fCtx)
|
||||||
if err := c.db.Model(&model.Product{}).Where("uid", c.Uid()).Updates(map[string]interface{}{"watch": true, "orderable": false}).Error; err != nil {
|
if err := c.db.Model(&model.Product{}).Where("uid", c.Uid()).Updates(map[string]interface{}{"watch": true, "orderable": false}).Error; err != nil {
|
||||||
|
@ -73,8 +73,8 @@ func (c *Controller) RunWatcher(opt *options.CoachOutletOption) error {
|
|||||||
uid := opt.Uid()
|
uid := opt.Uid()
|
||||||
err := c.db.Clauses(clause.OnConflict{
|
err := c.db.Clauses(clause.OnConflict{
|
||||||
Columns: []clause.Column{{Name: "uid"}},
|
Columns: []clause.Column{{Name: "uid"}},
|
||||||
DoUpdates: clause.AssignmentColumns([]string{"watch", "remark", "orderable", "pusher_ids", "deleted_at"}),
|
DoUpdates: clause.AssignmentColumns([]string{"pid", "watch", "remark", "orderable", "pusher_ids", "deleted_at"}),
|
||||||
}).Create(&model.Product{Uid: uid, Watch: true, Remark: opt.Remark, Orderable: false, PusherIds: opt.PusherIds}).Error
|
}).Create(&model.Product{Uid: uid, Pid: opt.Pid, Watch: true, Remark: opt.Remark, Orderable: false, PusherIds: opt.PusherIds}).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
28
server/proxy_svc.go
Normal file
28
server/proxy_svc.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
pool "haitao_watcher/pkg/pools"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProxySvc struct {
|
||||||
|
pool *pool.ProxyPool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProxySvc(pool *pool.ProxyPool) *ProxySvc {
|
||||||
|
return &ProxySvc{
|
||||||
|
pool: pool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxySvc) RegistryRouter(r fiber.Router) {
|
||||||
|
r.Get("proxies/status", s.GetStatusInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ProxySvc) GetStatusInfo(ctx fiber.Ctx) error {
|
||||||
|
list, updated := s.pool.Status()
|
||||||
|
return ctx.JSON(map[string]interface{}{
|
||||||
|
"list": list,
|
||||||
|
"updated": updated,
|
||||||
|
})
|
||||||
|
}
|
7
wwwroot/src/api/proxies.js
Normal file
7
wwwroot/src/api/proxies.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {mande} from "mande";
|
||||||
|
|
||||||
|
const pushers = mande('/api/v1/proxies')
|
||||||
|
|
||||||
|
export const getProxiesStatus = () => {
|
||||||
|
return pushers.get("/status")
|
||||||
|
}
|
@ -1,12 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-[100px] shadow-lg flex items-center px-12 space-x-4 z-10">
|
<div class="h-[100px] shadow-lg flex items-center justify-between px-12 z-10">
|
||||||
<img class="h-[60px]" src="@/assets/logo.png" alt="">
|
<div class="flex space-x-4 items-center">
|
||||||
<div class="text-[24px] font-bold">
|
<img class="h-[60px]" src="@/assets/logo.png" alt="">
|
||||||
可达鸭海淘蹲货
|
<div class="text-[24px] font-bold">
|
||||||
|
可达鸭海淘蹲货
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>当前代理个数: {{proxiesInfo.list.length}}</div>
|
||||||
|
<div class="text-[14px]">代理更新时间:{{moment(proxiesInfo.updated).format('YYYY-MM-DD HH:mm:ss')}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import {onMounted, reactive} from "vue";
|
||||||
|
import {getProxiesStatus} from "@/api/proxies.js";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
const proxiesInfo = reactive({
|
||||||
|
list:[],
|
||||||
|
updated: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
loadProxiesInfo()
|
||||||
|
})
|
||||||
|
const loadProxiesInfo = ()=>{
|
||||||
|
getProxiesStatus().then(res=>{
|
||||||
|
proxiesInfo.list = res.list
|
||||||
|
proxiesInfo.updated = res.updated
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
Loading…
Reference in New Issue
Block a user