package logic import ( "ecs/platform/wechat" "github.com/oylshe1314/framework/log" "github.com/oylshe1314/framework/server" "sync" "time" ) type WechatAccessTokenHolder struct { AccessToken string Expiration int64 } type CenterManager struct { logger log.Logger server server.Server closed bool wechatAccessTokenLocker sync.RWMutex wechatAccessTokenHolder *WechatAccessTokenHolder } func NewCenterManager(svr server.Server) *CenterManager { return &CenterManager{ logger: svr.Logger(), server: svr, } } func (this *CenterManager) Init() error { go this.tick() return nil } func (this *CenterManager) Close() error { this.closed = true return nil } func (this *CenterManager) tick() { var ticker = time.NewTicker(time.Second) defer ticker.Stop() for { now, ok := <-ticker.C if !ok || this.closed { return } this.checkRefreshWechatAccessToken(now.Unix()) } } func (this *CenterManager) checkRefreshWechatAccessToken(now int64) { this.wechatAccessTokenLocker.RLock() var holder = this.wechatAccessTokenHolder this.wechatAccessTokenLocker.RUnlock() if holder != nil { if now < holder.Expiration-240 { return } if now >= holder.Expiration { this.wechatAccessTokenLocker.Lock() this.wechatAccessTokenHolder = nil this.wechatAccessTokenLocker.Unlock() } } getAck, err := wechat.GetAccessToken() if err != nil { this.logger.Error("Wechar get access token error, ", err) return } if getAck.ErrCode != 0 { this.logger.Error("Wechar get access token code not 0, ", getAck.ErrMsg) return } if holder != nil && getAck.AccessToken == holder.AccessToken { return } this.logger.Debugf("Get access token success, accessToken: %s, expiration: %d, now: %d", getAck.AccessToken, getAck.ExpiresIn, now) syncAck, err := wechat.SyncAccessToken(getAck.AccessToken) if err != nil { this.logger.Error("Wechar sync access token error, ", err) return } if syncAck.Code != 200 { this.logger.Error("Wechar sync access token code not 200, ", syncAck.Msg) return } holder = &WechatAccessTokenHolder{ AccessToken: getAck.AccessToken, Expiration: now + getAck.ExpiresIn - 1, //假设接口返回有1秒延时 } this.wechatAccessTokenLocker.Lock() this.wechatAccessTokenHolder = holder this.wechatAccessTokenLocker.Unlock() } func (this *CenterManager) GetWechatAccessToken() string { this.wechatAccessTokenLocker.RLock() var holder = this.wechatAccessTokenHolder this.wechatAccessTokenLocker.RUnlock() if holder == nil { return "" } else { return holder.AccessToken } } func (this *CenterManager) RefreshWechatAccessToken(appId string) string { if appId != wechat.AppId() { return "" } this.wechatAccessTokenLocker.Lock() this.wechatAccessTokenHolder = nil this.wechatAccessTokenLocker.Unlock() for i := 0; i < 30; i++ { time.Sleep(time.Second) this.wechatAccessTokenLocker.RLock() var holder = this.wechatAccessTokenHolder this.wechatAccessTokenLocker.RUnlock() if holder != nil { return holder.AccessToken } } return "" }