|
|
@ -11,7 +11,6 @@ import ( |
|
|
|
"net/http" |
|
|
|
"os" |
|
|
|
"runtime" |
|
|
|
"sync" |
|
|
|
"time" |
|
|
|
) |
|
|
|
|
|
|
@ -21,7 +20,7 @@ var cookieJar *httpc.CookieJar |
|
|
|
|
|
|
|
var config *goconfig.ConfigFile |
|
|
|
|
|
|
|
var wg *sync.WaitGroup |
|
|
|
var seckillStatus chan bool |
|
|
|
|
|
|
|
func init() { |
|
|
|
//客户端设置初始化
|
|
|
@ -40,8 +39,8 @@ func init() { |
|
|
|
os.Exit(0) |
|
|
|
} |
|
|
|
|
|
|
|
wg=new(sync.WaitGroup) |
|
|
|
wg.Add(1) |
|
|
|
//抢购状态管道
|
|
|
|
seckillStatus=make(chan bool) |
|
|
|
} |
|
|
|
|
|
|
|
func main() { |
|
|
@ -64,16 +63,19 @@ func main() { |
|
|
|
_,err=user.TicketInfo(ticket) |
|
|
|
if err==nil { |
|
|
|
log.Println("登录成功") |
|
|
|
//刷新用户状态和获取用户信息
|
|
|
|
//刷新用户状态
|
|
|
|
if status:=user.RefreshStatus();status==nil { |
|
|
|
//活跃用户会话,当会话失效自动退出程序
|
|
|
|
go KeepSession(user) |
|
|
|
//获取用户信息
|
|
|
|
userInfo,_:=user.GetUserInfo() |
|
|
|
log.Println("用户:"+userInfo) |
|
|
|
//开始预约,预约过的就重复预约
|
|
|
|
seckill:=jd_seckill.NewSeckill(client,config) |
|
|
|
seckill.MakeReserve() |
|
|
|
//等待抢购/开始抢购
|
|
|
|
//计算抢购时间
|
|
|
|
nowLocalTime:=time.Now().UnixNano()/1e6 |
|
|
|
jdTime,_:=getJdTime() |
|
|
|
jdTime,_:=GetJdTime() |
|
|
|
buyDate:=config.MustValue("config","buy_time","") |
|
|
|
loc, _ := time.LoadLocation("Local") |
|
|
|
t,_:=time.ParseInLocation("2006-01-02 15:04:05",buyDate,loc) |
|
|
@ -85,18 +87,22 @@ func main() { |
|
|
|
log.Println("请设置抢购时间") |
|
|
|
os.Exit(0) |
|
|
|
} |
|
|
|
//等待抢购
|
|
|
|
time.Sleep(time.Duration(timerTime)*time.Millisecond) |
|
|
|
//开启任务
|
|
|
|
//开始抢购
|
|
|
|
log.Println("时间到达,开始执行……") |
|
|
|
start(seckill,5) |
|
|
|
wg.Wait() |
|
|
|
//开启抢购任务,第二个参数为开启几个协程
|
|
|
|
//怕封号的可以减少协程数量,相反抢到的成功率也减低了
|
|
|
|
Start(seckill,5) |
|
|
|
}else{ |
|
|
|
log.Println("登录失效") |
|
|
|
} |
|
|
|
}else{ |
|
|
|
log.Println("登录失败") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func getJdTime() (int64,error) { |
|
|
|
func GetJdTime() (int64,error) { |
|
|
|
req:=httpc.NewRequest(client) |
|
|
|
resp,body,err:=req.SetUrl("https://a.jd.com//ajax/queryServerData.html").SetMethod("get").Send().End() |
|
|
|
if err!=nil || resp.StatusCode!=http.StatusOK { |
|
|
@ -106,12 +112,54 @@ func getJdTime() (int64,error) { |
|
|
|
return gjson.Get(body,"serverTime").Int(),nil |
|
|
|
} |
|
|
|
|
|
|
|
func start(seckill *jd_seckill.Seckill,taskNum int) { |
|
|
|
for i:=1;i<=taskNum;i++ { |
|
|
|
go func(seckill *jd_seckill.Seckill) { |
|
|
|
seckill.RequestSeckillUrl() |
|
|
|
seckill.SeckillPage() |
|
|
|
seckill.SubmitSeckillOrder() |
|
|
|
}(seckill) |
|
|
|
func Start(seckill *jd_seckill.Seckill,taskNum int) { |
|
|
|
seckillTotalTime:=time.Now().Add(2*time.Minute).Unix() |
|
|
|
//开始检测抢购状态
|
|
|
|
go CheckSeckillStatus() |
|
|
|
//抢购总时间两分钟,超时程序自动退出
|
|
|
|
for time.Now().Unix()<seckillTotalTime { |
|
|
|
for i:=1;i<=taskNum;i++ { |
|
|
|
go task(seckill) |
|
|
|
} |
|
|
|
//每隔1.5秒执行一次
|
|
|
|
//怕封号的可以增加间隔时间,相反抢到的成功率也减低了
|
|
|
|
time.Sleep(1500*time.Millisecond) |
|
|
|
} |
|
|
|
log.Println("抢购结束,具体详情请查看日志") |
|
|
|
} |
|
|
|
|
|
|
|
func task(seckill *jd_seckill.Seckill) { |
|
|
|
seckill.RequestSeckillUrl() |
|
|
|
seckill.SeckillPage() |
|
|
|
flag:=seckill.SubmitSeckillOrder() |
|
|
|
//提前抢购成功的,直接结束程序
|
|
|
|
if flag { |
|
|
|
//通知管道
|
|
|
|
seckillStatus<-true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func CheckSeckillStatus() { |
|
|
|
for { |
|
|
|
select { |
|
|
|
case <-seckillStatus: |
|
|
|
//抢购成功,程序退出
|
|
|
|
os.Exit(0) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func KeepSession(user *jd_seckill.User) { |
|
|
|
//每30分钟检测一次
|
|
|
|
t:=time.NewTicker(30*time.Minute) |
|
|
|
for { |
|
|
|
select { |
|
|
|
case <-t.C: |
|
|
|
if err:=user.RefreshStatus();err!=nil { |
|
|
|
log.Println("会话失效,程序自动退出") |
|
|
|
os.Exit(0) |
|
|
|
} |
|
|
|
log.Println("活跃会话成功") |
|
|
|
} |
|
|
|
} |
|
|
|
} |