241 lines
6.1 KiB
Go
241 lines
6.1 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strconv"
|
||
"time"
|
||
|
||
"go-common/library/cache/redis"
|
||
"go-common/library/log"
|
||
|
||
farm "github.com/dgryski/go-farm"
|
||
)
|
||
|
||
const (
|
||
// aid_ip
|
||
_anonymousePlayedKey = "nm:%d"
|
||
// aid bvid
|
||
_anonymouseBvIDKey = "nb:%d"
|
||
// bvid's last played aid
|
||
_bvIDLastPlayedKey = "bv:%d"
|
||
// Mid last played key
|
||
_midHashKey = "mid:%d"
|
||
_buvidToDidKey = "%d:bdid"
|
||
// 改短成6分钟
|
||
_hkeyExpire = 600
|
||
)
|
||
|
||
func (s *Service) midKey(mid int64) (key string) {
|
||
key = fmt.Sprintf(_midHashKey, mid%s.c.HashNum)
|
||
return
|
||
}
|
||
|
||
func (s *Service) bvKey(bvID string) (key string) {
|
||
num := int64(farm.Hash32([]byte(bvID)))
|
||
key = fmt.Sprintf(_bvIDLastPlayedKey, num%s.c.HashNum)
|
||
return
|
||
}
|
||
|
||
func (s *Service) buvidToDidKey(buvid string, aid int64) (key string) {
|
||
num := int64(farm.Hash32([]byte(fmt.Sprintf("%s_%d", buvid, aid))))
|
||
key = fmt.Sprintf(_buvidToDidKey, num%s.c.HashNum)
|
||
return
|
||
}
|
||
|
||
func (s *Service) anonymouseKey(aid, epID int64, ip string) (key string) {
|
||
var str string
|
||
if epID == 0 {
|
||
str = strconv.Itoa(int(aid)) + ip
|
||
} else {
|
||
str = strconv.Itoa(int(aid)) + ip + strconv.Itoa(int(epID))
|
||
}
|
||
num := int64(farm.Hash32([]byte(str)))
|
||
key = fmt.Sprintf(_anonymousePlayedKey, num%s.c.HashNum)
|
||
return
|
||
}
|
||
|
||
func (s *Service) anonymouseBvIDKey(aid int64, bvid string) (key string) {
|
||
str := strconv.Itoa(int(aid)) + bvid
|
||
num := int64(farm.Hash32([]byte(str)))
|
||
key = fmt.Sprintf(_anonymouseBvIDKey, num%s.c.HashNum)
|
||
return
|
||
}
|
||
|
||
// canCount 同一个IP一分钟,同一个bvid五分钟
|
||
func (s *Service) canCount(c context.Context, aid, epID int64, ip string, stime int64, bvid string) (can bool) {
|
||
var (
|
||
err error
|
||
lastPlayTime int64
|
||
bvLastPlayTime int64
|
||
hKey = s.anonymouseKey(aid, epID, ip)
|
||
hbvKey = s.anonymouseBvIDKey(aid, bvid)
|
||
conn = s.redis.Get(c)
|
||
pTime = stime + s.c.CacheConf.NewAnonymousCacheTime
|
||
now = time.Now().Unix()
|
||
ipCan bool
|
||
bvCan bool
|
||
)
|
||
var field = aid
|
||
if epID > 0 {
|
||
field = epID
|
||
}
|
||
defer conn.Close()
|
||
if lastPlayTime, err = redis.Int64(conn.Do("HGET", hKey, field)); err != nil {
|
||
if err == redis.ErrNil {
|
||
if _, err = conn.Do("HSET", hKey, field, pTime); err != nil {
|
||
log.Error("conn.Do(HSET, %s, %d, %d) error(%v)", hKey, field, pTime, err)
|
||
return
|
||
}
|
||
ipCan = true
|
||
} else {
|
||
log.Error("conn.Do(HGET, %s, %d) error(%v)", hKey, field, err)
|
||
return
|
||
}
|
||
}
|
||
if bvLastPlayTime, err = redis.Int64(conn.Do("HGET", hbvKey, field)); err != nil {
|
||
if err == redis.ErrNil {
|
||
if _, err = conn.Do("HSET", hbvKey, field, pTime); err != nil {
|
||
log.Error("conn.Do(HSET, %s, %d, %d)", hbvKey, field, pTime)
|
||
return
|
||
}
|
||
bvCan = true
|
||
} else {
|
||
log.Error("conn.Do(HGET, %s, %d) error(%v)", hbvKey, field, err)
|
||
return
|
||
}
|
||
}
|
||
if ipCan && bvCan {
|
||
can = true
|
||
return
|
||
}
|
||
if now > lastPlayTime && now > bvLastPlayTime {
|
||
if err = conn.Send("HSET", hKey, field, now+s.c.CacheConf.NewAnonymousCacheTime); err != nil {
|
||
log.Error("conn.Send(HSET, %s, %s, %d) error(%v)", hKey, field, now+s.c.CacheConf.NewAnonymousCacheTime, err)
|
||
return
|
||
}
|
||
if err = conn.Send("EXPIRE", hKey, _hkeyExpire); err != nil {
|
||
log.Error("conn.Do(EXPIRE, %s, %d) error(%v)", hKey, _hkeyExpire, err)
|
||
return
|
||
}
|
||
if err = conn.Send("HSET", hbvKey, field, now+s.c.CacheConf.NewAnonymousBvCacheTime); err != nil {
|
||
log.Error("conn.Send(HSET, %s, %d, %d) error(%v)", hbvKey, field, now+s.c.CacheConf.NewAnonymousBvCacheTime, err)
|
||
return
|
||
}
|
||
if err = conn.Send("EXPIRE", hbvKey, _hkeyExpire); err != nil {
|
||
log.Error("conn.Do(EXPIRE, %s, %d) error(%v)", hbvKey, _hkeyExpire, err)
|
||
return
|
||
}
|
||
if err = conn.Flush(); err != nil {
|
||
log.Error("conn.Flush error(%v)")
|
||
return
|
||
}
|
||
for i := 0; i < 4; i++ {
|
||
if _, err = conn.Receive(); err != nil {
|
||
log.Error("conn.Receive error(%v)", err)
|
||
return
|
||
}
|
||
}
|
||
can = true
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *Service) isReplay(c context.Context, mid, aid int64, bvID string, gapTime int64) (is bool) {
|
||
var (
|
||
hKey string
|
||
field string
|
||
conn = s.redis.Get(c)
|
||
value int64
|
||
err error
|
||
now = time.Now().Unix()
|
||
)
|
||
defer conn.Close()
|
||
if mid > 0 {
|
||
hKey = s.midKey(mid)
|
||
field = strconv.Itoa(int(mid))
|
||
} else {
|
||
hKey = s.bvKey(bvID)
|
||
field = bvID
|
||
}
|
||
// aid << 32 | ptime
|
||
if value, err = redis.Int64(conn.Do("HGET", hKey, field)); err != nil {
|
||
if err != redis.ErrNil {
|
||
log.Error("conn.Do(HGET, %s, %s) error(%s)", hKey, field, err)
|
||
return
|
||
}
|
||
err = nil
|
||
}
|
||
if value != 0 {
|
||
rOid := value >> 32
|
||
rNow := value & 0xffffffff
|
||
if rOid == aid && now-rNow < gapTime {
|
||
is = true
|
||
return
|
||
}
|
||
}
|
||
value = aid<<32 | now
|
||
if err = conn.Send("HSET", hKey, field, value); err != nil {
|
||
log.Error("conn.Do(HSET, %s, %s, %s) error(%v)", hKey, field, value, err)
|
||
return
|
||
}
|
||
if err = conn.Send("EXPIRE", hKey, _hkeyExpire); err != nil {
|
||
log.Error("conn.Do(EXPIRE, %s, %d)", hKey, _hkeyExpire)
|
||
return
|
||
}
|
||
if err = conn.Flush(); err != nil {
|
||
log.Error("conn.Flush error(%v)")
|
||
return
|
||
}
|
||
for i := 0; i < 2; i++ {
|
||
if _, err = conn.Receive(); err != nil {
|
||
log.Error("conn.Receive error(%v)", err)
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *Service) getRealDid(c context.Context, buvid string, aid int64) (did string, err error) {
|
||
var (
|
||
conn = s.redis.Get(c)
|
||
key = s.buvidToDidKey(buvid, aid)
|
||
)
|
||
defer conn.Close()
|
||
if did, err = redis.String(conn.Do("HGET", key, buvid)); err != nil {
|
||
if err != redis.ErrNil {
|
||
log.Error("redis.String(conn.Do(HGET, %s, %s)) error(%v)", key, buvid, err)
|
||
return
|
||
}
|
||
err = nil
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *Service) setRealDid(c context.Context, buvid string, aid int64, did string) (err error) {
|
||
var (
|
||
conn = s.redis.Get(c)
|
||
key = s.buvidToDidKey(buvid, aid)
|
||
)
|
||
defer conn.Close()
|
||
if err = conn.Send("HSET", key, buvid, did); err != nil {
|
||
log.Error("conn.Do(HSET, %s, %s, %s) error(%v)", key, buvid, did, err)
|
||
return
|
||
}
|
||
if err = conn.Send("EXPIRE", key, _hkeyExpire); err != nil {
|
||
log.Error("conn.Send(EXPIRE, %s, %d) error(%v)", key, _hkeyExpire, err)
|
||
return
|
||
}
|
||
if err = conn.Flush(); err != nil {
|
||
log.Error("conn.Flush error(%v)", err)
|
||
return
|
||
}
|
||
for i := 0; i < 2; i++ {
|
||
if _, err = conn.Receive(); err != nil {
|
||
log.Error("conn.Receive error(%v)", err)
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|