Browse Source

ws offline logic...

master
tangmingyou 3 years ago
parent
commit
f3d524bfa5
  1. 4
      cmd/main.go
  2. 1
      data/config.toml
  3. 3
      internal/server/ws.go
  4. 2
      internal/service/auth.go
  5. 20
      internal/service/event/offline.go
  6. 8
      internal/service/event/online.go
  7. 3
      internal/session/net_account.go
  8. 1
      internal/session/net_client.go
  9. 2
      tool/watcher/watcher.go

4
cmd/main.go

@ -27,7 +27,7 @@ func main() {
//fmt.Println(k, v) //fmt.Println(k, v)
//wait := &sync.WaitGroup{} //wait := &sync.WaitGroup{}
//wait.Add(1) //wait.Publish(1)
//wait.Wait() //wait.Wait()
//wait := make(chan bool, 1) //wait := make(chan bool, 1)
@ -38,7 +38,7 @@ func main() {
//var counters [10]*atomic.Int32 //var counters [10]*atomic.Int32
// //
//delayer := async.NewScheduleQueue(time.Second, 32, func(index int32, now time.Time) int32 { //delayer := async.NewScheduleQueue(time.Second, 32, func(index int32, now time.Time) int32 {
// counters[index%100].Add(1) // counters[index%100].Publish(1)
// fmt.Println(now.Format("2006-01-02 15:04:05.9999"), index, index%100, counters[index%100].Load()) // fmt.Println(now.Format("2006-01-02 15:04:05.9999"), index, index%100, counters[index%100].Load())
// if index == 10000 && counters[index%100].Load() == 1000 { // if index == 10000 && counters[index%100].Load() == 1000 {
// wait <- true // wait <- true

1
data/config.toml

@ -1,6 +1,7 @@
[http] [http]
host = "" host = ""
#host = "192.168.3.101"
port = 3999 port = 3999
[auth] [auth]

3
internal/server/ws.go

@ -84,7 +84,8 @@ func handleNetClient(client *session.NetClient) {
}() }()
defer func() { defer func() {
if client.Account != nil { if client.Account != nil {
event.OfflineWatcher.Add(client.Account.Id, true) client.Online.Store(false)
event.OfflineWatcher.Publish(client.Account.Id, true)
} }
}() }()
// https://github.com/gorilla/websocket/blob/a68708917c6a4f06314ab4e52493cc61359c9d42/examples/chat/conn.go#L50 // https://github.com/gorilla/websocket/blob/a68708917c6a4f06314ab4e52493cc61359c9d42/examples/chat/conn.go#L50

2
internal/service/auth.go

@ -253,7 +253,7 @@ func HandleReqIdentity(client *session.NetClient, msg *api.ReqIdentity) (proto.M
client.Account = account client.Account = account
// 在线通知消息 // 在线通知消息
event.OnlineWatcher.Add(account.Id, true) event.OnlineWatcher.Publish(account.Id, true)
// response // response
res := &api.ResIdentity{Id: subject.Id, Username: subject.Name, Avatar: subject.Avatar} res := &api.ResIdentity{Id: subject.Id, Username: subject.Name, Avatar: subject.Avatar}

20
internal/service/event/offline.go

@ -3,7 +3,7 @@ package event
import ( import (
"fmt" "fmt"
"texas-poker-bk/internal/service/store" "texas-poker-bk/internal/service/store"
"texas-poker-bk/internal/session" "texas-poker-bk/tool/async"
"texas-poker-bk/tool/collect" "texas-poker-bk/tool/collect"
"texas-poker-bk/tool/watcher" "texas-poker-bk/tool/watcher"
"time" "time"
@ -13,14 +13,14 @@ var (
// OfflineWatcher 离线动作 // OfflineWatcher 离线动作
OfflineWatcher *watcher.Watcher[int64, bool] OfflineWatcher *watcher.Watcher[int64, bool]
//OfflineQueue *collect.DelayQueue[*session.NetAccount] offlineCleanDelayer *async.DelayQueue[int64]
) )
func init() { func init() {
OfflineWatcher = watcher.NewWatcher(128, handleOffline) OfflineWatcher = watcher.NewWatcher(128, handleOffline)
go OfflineWatcher.Run() go OfflineWatcher.Run()
offlineCleanDelayer = async.NewDelayQueue(time.Second, 128, removeMemoryAccount)
} }
func handleOffline(e *watcher.Event[int64, bool]) { func handleOffline(e *watcher.Event[int64, bool]) {
@ -33,15 +33,15 @@ func handleOffline(e *watcher.Event[int64, bool]) {
return return
} }
if account.Player == nil { if account.Player == nil {
// 不在游戏中,直接下线 // 不在游戏中,n秒后移除
removeMemoryAccount(account) account.OfflineCleanCanceler = offlineCleanDelayer.Delay(10*time.Second, account.Id)
return return
} }
if collect.In(account.Player.GameTable.Stage, 1, 9) { if collect.In(account.Player.GameTable.Stage, 1, 9) {
// 牌局未在进行中直接移除玩家并下线 // 牌局未在进行中直接移除玩家并下线
account.Player.GameTable.RemovePlayer(account.Id) account.Player.GameTable.RemovePlayer(account.Id)
account.SettlePlayerChip() account.SettlePlayerChip()
removeMemoryAccount(account) account.OfflineCleanCanceler = offlineCleanDelayer.Delay(10*time.Second, account.Id)
return return
} }
// 判断当前是玩家回合(60s自动过牌/弃牌) // 判断当前是玩家回合(60s自动过牌/弃牌)
@ -51,8 +51,10 @@ func handleOffline(e *watcher.Event[int64, bool]) {
// 待玩家回合时还是offline(自动过牌/弃牌) // 待玩家回合时还是offline(自动过牌/弃牌)
} }
func removeMemoryAccount(account *session.NetAccount) { // func removeMemoryAccount(account *session.NetAccount) {
store.NetAccounts.Delete(account.Id) func removeMemoryAccount(accountId int64, now time.Time) {
store.TokenVersions.Delete(account.Id) _ = store.NetAccounts.Get(accountId)
store.NetAccounts.Delete(accountId)
store.TokenVersions.Delete(accountId)
// TODO 持久化账户金额 // TODO 持久化账户金额
} }

8
internal/service/event/online.go

@ -16,7 +16,13 @@ func init() {
// handleOnline 玩家上线了,取消一些自动操作动作 // handleOnline 玩家上线了,取消一些自动操作动作
func handleOnline(e *watcher.Event[int64, bool]) { func handleOnline(e *watcher.Event[int64, bool]) {
account := store.NetAccounts.Get(e.Publisher) account := store.NetAccounts.Get(e.Publisher)
if account == nil || account.Player == nil { if account == nil {
return
}
if account.OfflineCleanCanceler != nil {
account.OfflineCleanCanceler.Cancel()
}
if account.Player == nil {
return return
} }
// 取消自动下注 // 取消自动下注

3
internal/session/net_account.go

@ -3,6 +3,7 @@ package session
import ( import (
"sync" "sync"
"texas-poker-bk/internal/game" "texas-poker-bk/internal/game"
"texas-poker-bk/tool/async"
) )
// NetAccount 已认证的长连接用户 // NetAccount 已认证的长连接用户
@ -15,6 +16,8 @@ type NetAccount struct {
Player *game.Player Player *game.Player
BalanceLock *sync.RWMutex BalanceLock *sync.RWMutex
Lock *sync.Mutex Lock *sync.Mutex
OfflineCleanCanceler *async.Canceler[int64]
} }
func (account *NetAccount) DecrementBalance(amount int32) int32 { func (account *NetAccount) DecrementBalance(amount int32) int32 {

1
internal/session/net_client.go

@ -33,7 +33,6 @@ func NewNetClient(conn *websocket.Conn) *NetClient {
func (c *NetClient) Close(reason string) { func (c *NetClient) Close(reason string) {
log.Println("close NetClient reason: ", reason) log.Println("close NetClient reason: ", reason)
c.Online.Store(false)
err := c.Conn.Close() err := c.Conn.Close()
if err != nil { if err != nil {
log.Println("Close Error", err) log.Println("Close Error", err)

2
tool/watcher/watcher.go

@ -39,7 +39,7 @@ func (w *Watcher[P, T]) Stop() {
w.stop <- true w.stop <- true
} }
func (w *Watcher[P, T]) Add(publisher P, event T) { func (w *Watcher[P, T]) Publish(publisher P, event T) {
e := &Event[P, T]{publisher, event, time.Now().UnixMilli()} e := &Event[P, T]{publisher, event, time.Now().UnixMilli()}
go func() { go func() {
w.events <- e w.events <- e

Loading…
Cancel
Save