feat(player): 添加玩家登录状态检查和等待机制
- 在 Player 结构中添加登录状态标志和登录完成通知通道 - 实现 IsLoggedIn、WaitForLogin、WaitForLoginWithTimeout 和 WaitForLoginWithCtx 方法 - 在登录逻辑中使用 CompleteLogin 标记登录完成并通知等待者 - 在控制器中添加登录状态检查,确保处理已登录玩家的请求
This commit is contained in:
@@ -2,6 +2,10 @@ package entity
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
)
|
||||
@@ -10,7 +14,9 @@ type Player struct {
|
||||
MainConn Conn
|
||||
UserID uint32 //用户ID
|
||||
IsLogin bool //是否登录 //TODO 待实现登录包为第一个包,后续再发其他的包
|
||||
mu sync.Mutex
|
||||
|
||||
loginChan chan struct{} // 登录完成通知通道
|
||||
}
|
||||
|
||||
// PlayerOption 定义配置 Player 的函数类型
|
||||
@@ -30,7 +36,9 @@ func WithConn(c gnet.Conn) PlayerOption {
|
||||
|
||||
// NewPlayer 使用 Options 模式创建 Player 实例
|
||||
func NewPlayer(opts ...PlayerOption) *Player {
|
||||
p := &Player{}
|
||||
p := &Player{
|
||||
loginChan: make(chan struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(p)
|
||||
}
|
||||
@@ -56,3 +64,64 @@ func ConutPlayer() int {
|
||||
return count
|
||||
//fmt.Println("元素数量:", count) // 输出: 3
|
||||
}
|
||||
|
||||
// IsLoggedIn 检查是否已登录
|
||||
func (lw *Player) IsLoggedIn() bool {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
return lw.IsLogin
|
||||
}
|
||||
|
||||
// WaitForLogin 等待登录完成,无超时
|
||||
func (lw *Player) WaitForLogin() error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 阻塞等待登录完成
|
||||
<-lw.loginChan
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForLoginWithTimeout 带超时的登录等待
|
||||
func (lw *Player) WaitForLoginWithTimeout(timeout time.Duration) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 使用定时器实现超时
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-timer.C:
|
||||
return fmt.Errorf("登录等待超时: %v", timeout)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForLoginWithCtx 带上下文的登录等待
|
||||
func (lw *Player) WaitForLoginWithCtx(ctx context.Context) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err() // 上下文取消或超时
|
||||
}
|
||||
}
|
||||
|
||||
// CompleteLogin 标记登录完成并通知等待者
|
||||
func (lw *Player) CompleteLogin() {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
|
||||
if !lw.IsLogin {
|
||||
lw.IsLogin = true
|
||||
close(lw.loginChan) // 关闭通道以通知所有等待者
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user