添加定时同步数据到热存储容器功能 (#191)
This commit is contained in:
parent
102af677ff
commit
87036e2c94
7
bot.go
7
bot.go
@ -248,7 +248,7 @@ func (b *Bot) Block() error {
|
|||||||
if b.self == nil {
|
if b.self == nil {
|
||||||
return errors.New("`Block` must be called after user login")
|
return errors.New("`Block` must be called after user login")
|
||||||
}
|
}
|
||||||
<-b.context.Done()
|
<-b.Context().Done()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +298,11 @@ func (b *Bot) UUID() string {
|
|||||||
return b.uuid
|
return b.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Context returns current context of bot
|
||||||
|
func (b *Bot) Context() context.Context {
|
||||||
|
return b.context
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Bot) reload() error {
|
func (b *Bot) reload() error {
|
||||||
if b.hotReloadStorage == nil {
|
if b.hotReloadStorage == nil {
|
||||||
return errors.New("hotReloadStorage is nil")
|
return errors.New("hotReloadStorage is nil")
|
||||||
|
54
bot_login.go
54
bot_login.go
@ -1,5 +1,9 @@
|
|||||||
package openwechat
|
package openwechat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// BotLogin 定义了一个Login的接口
|
// BotLogin 定义了一个Login的接口
|
||||||
type BotLogin interface {
|
type BotLogin interface {
|
||||||
Login(bot *Bot) error
|
Login(bot *Bot) error
|
||||||
@ -28,8 +32,9 @@ func (s *SacnLogin) checkLogin(bot *Bot, uuid string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type hotLoginOption struct {
|
type hotLoginOption struct {
|
||||||
withRetry bool
|
withRetry bool
|
||||||
_ struct{}
|
syncDuration time.Duration
|
||||||
|
_ struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type HotLoginOptionFunc func(o *hotLoginOption)
|
type HotLoginOptionFunc func(o *hotLoginOption)
|
||||||
@ -40,6 +45,13 @@ func HotLoginWithRetry(flag bool) HotLoginOptionFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HotLoginWithSyncReloadData 定时同步 HotLogin 的数据
|
||||||
|
func HotLoginWithSyncReloadData(duration time.Duration) HotLoginOptionFunc {
|
||||||
|
return func(o *hotLoginOption) {
|
||||||
|
o.syncDuration = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HotLogin 热登录模式
|
// HotLogin 热登录模式
|
||||||
type HotLogin struct {
|
type HotLogin struct {
|
||||||
storage HotReloadStorage
|
storage HotReloadStorage
|
||||||
@ -48,6 +60,17 @@ type HotLogin struct {
|
|||||||
|
|
||||||
// Login 实现了 BotLogin 接口
|
// Login 实现了 BotLogin 接口
|
||||||
func (h *HotLogin) Login(bot *Bot) error {
|
func (h *HotLogin) Login(bot *Bot) error {
|
||||||
|
if err := h.loginWrapper(bot); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if h.opt.syncDuration > 0 {
|
||||||
|
syncer := NewHotReloadStorageSyncer(bot, h.opt.syncDuration)
|
||||||
|
go func() { _ = syncer.Sync() }()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HotLogin) loginWrapper(bot *Bot) error {
|
||||||
err := h.login(bot)
|
err := h.login(bot)
|
||||||
if err != nil && h.opt.withRetry {
|
if err != nil && h.opt.withRetry {
|
||||||
scanLogin := SacnLogin{}
|
scanLogin := SacnLogin{}
|
||||||
@ -73,6 +96,7 @@ type pushLoginOption struct {
|
|||||||
withoutScanCallback bool
|
withoutScanCallback bool
|
||||||
withoutLoginCallback bool
|
withoutLoginCallback bool
|
||||||
withRetry bool
|
withRetry bool
|
||||||
|
syncDuration time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type PushLoginOptionFunc func(o *pushLoginOption)
|
type PushLoginOptionFunc func(o *pushLoginOption)
|
||||||
@ -105,6 +129,13 @@ func PushLoginWithRetry(flag bool) PushLoginOptionFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PushLoginWithSyncReloadData 定时同步 PushLogin 的数据
|
||||||
|
func PushLoginWithSyncReloadData(duration time.Duration) PushLoginOptionFunc {
|
||||||
|
return func(o *pushLoginOption) {
|
||||||
|
o.syncDuration = duration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// defaultPushLoginOpts 默认的 PushLogin
|
// defaultPushLoginOpts 默认的 PushLogin
|
||||||
var defaultPushLoginOpts = [...]PushLoginOptionFunc{
|
var defaultPushLoginOpts = [...]PushLoginOptionFunc{
|
||||||
PushLoginWithoutUUIDCallback(true),
|
PushLoginWithoutUUIDCallback(true),
|
||||||
@ -118,7 +149,18 @@ type PushLogin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Login 实现了 BotLogin 接口
|
// Login 实现了 BotLogin 接口
|
||||||
func (p PushLogin) Login(bot *Bot) error {
|
func (p *PushLogin) Login(bot *Bot) error {
|
||||||
|
if err := p.loginWrapper(bot); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if p.opt.syncDuration > 0 {
|
||||||
|
syncer := NewHotReloadStorageSyncer(bot, p.opt.syncDuration)
|
||||||
|
go func() { _ = syncer.Sync() }()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PushLogin) loginWrapper(bot *Bot) error {
|
||||||
err := p.login(bot)
|
err := p.login(bot)
|
||||||
if err != nil && p.opt.withRetry {
|
if err != nil && p.opt.withRetry {
|
||||||
scanLogin := SacnLogin{}
|
scanLogin := SacnLogin{}
|
||||||
@ -127,7 +169,7 @@ func (p PushLogin) Login(bot *Bot) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PushLogin) login(bot *Bot) error {
|
func (p *PushLogin) login(bot *Bot) error {
|
||||||
if err := p.pushLoginInit(bot); err != nil {
|
if err := p.pushLoginInit(bot); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -141,13 +183,13 @@ func (p PushLogin) login(bot *Bot) error {
|
|||||||
return p.checkLogin(bot, resp.UUID)
|
return p.checkLogin(bot, resp.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p PushLogin) pushLoginInit(bot *Bot) error {
|
func (p *PushLogin) pushLoginInit(bot *Bot) error {
|
||||||
bot.hotReloadStorage = p.storage
|
bot.hotReloadStorage = p.storage
|
||||||
return bot.reload()
|
return bot.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkLogin 登录检查
|
// checkLogin 登录检查
|
||||||
func (p PushLogin) checkLogin(bot *Bot, uuid string) error {
|
func (p *PushLogin) checkLogin(bot *Bot, uuid string) error {
|
||||||
bot.uuid = uuid
|
bot.uuid = uuid
|
||||||
loginChecker := &LoginChecker{
|
loginChecker := &LoginChecker{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
|
28
stroage.go
28
stroage.go
@ -3,6 +3,7 @@ package openwechat
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Storage 身份信息, 维持整个登陆的Session会话
|
// Storage 身份信息, 维持整个登陆的Session会话
|
||||||
@ -75,3 +76,30 @@ func NewJsonFileHotReloadStorage(filename string) io.ReadWriteCloser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ HotReloadStorage = (*jsonFileHotReloadStorage)(nil)
|
var _ HotReloadStorage = (*jsonFileHotReloadStorage)(nil)
|
||||||
|
|
||||||
|
type HotReloadStorageSyncer struct {
|
||||||
|
duration time.Duration
|
||||||
|
bot *Bot
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync 定时同步数据到登陆存储中
|
||||||
|
func (h *HotReloadStorageSyncer) Sync() error {
|
||||||
|
// 定时器
|
||||||
|
ticker := time.NewTicker(h.duration)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
// 每隔一段时间, 将数据同步到storage中
|
||||||
|
if err := h.bot.DumpHotReloadStorage(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case <-h.bot.Context().Done():
|
||||||
|
// 当Bot关闭的时候, 退出循环
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHotReloadStorageSyncer(bot *Bot, duration time.Duration) *HotReloadStorageSyncer {
|
||||||
|
return &HotReloadStorageSyncer{duration: duration, bot: bot}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user