csconnectplayerlogic.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package logic
  2. import (
  3. "context"
  4. "github.com/bytedance/sonic"
  5. "github.com/gookit/event"
  6. treemap "github.com/liyue201/gostl/ds/map"
  7. "github.com/pkg/errors"
  8. "github.com/robfig/cron/v3"
  9. "github.com/zeromicro/go-zero/core/logx"
  10. "time"
  11. "ylink/comm/globalkey"
  12. "ylink/comm/model"
  13. "ylink/comm/result"
  14. "ylink/core/inner/rpc/internal/ext"
  15. "ylink/core/inner/rpc/internal/svc"
  16. "ylink/core/inner/rpc/pb"
  17. )
  18. type CsConnectPlayerLogic struct {
  19. ctx context.Context
  20. svcCtx *svc.ServiceContext
  21. logx.Logger
  22. }
  23. func NewCsConnectPlayerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CsConnectPlayerLogic {
  24. return &CsConnectPlayerLogic{
  25. ctx: ctx,
  26. svcCtx: svcCtx,
  27. Logger: logx.WithContext(ctx),
  28. }
  29. }
  30. func (l *CsConnectPlayerLogic) CsConnectPlayer(in *pb.InnerCsConnectPlayerReq) (*pb.InnerCsConnectPlayerResp, error) {
  31. playerInfo := ext.GetOnlinePlayerInfo(in.GameId, in.PlayerId)
  32. if playerInfo == nil {
  33. return nil, errors.Wrapf(result.NewErrMsg("The player is not connected"), "")
  34. }
  35. playerInfo.CsId = in.CsId
  36. playerInfo.DequeueTs = time.Now().Unix()
  37. if ext.GameConnectedMap.Contains(in.GameId) {
  38. playerConnectedMap := ext.GameConnectedMap.Get(in.GameId).(*treemap.Map)
  39. playerConnectedMap.Insert(in.PlayerId, playerInfo)
  40. } else {
  41. playerConnectedMap := treemap.New(treemap.WithGoroutineSafe())
  42. playerConnectedMap.Insert(in.PlayerId, playerInfo)
  43. ext.GameConnectedMap.Insert(in.GameId, playerConnectedMap)
  44. }
  45. // 移除WaitingQueue
  46. for n := ext.WaitingList.FrontNode(); n != nil; n = n.Next() {
  47. playerInfo := n.Value.(*model.PlayerInfo)
  48. if playerInfo.GameId == in.GameId && playerInfo.PlayerId == in.PlayerId {
  49. l.Logger.Infof("remove the player from the queue, game_id: %s, player_id: %s", in.GameId, in.PlayerId)
  50. ext.WaitingList.Remove(nil, n)
  51. break
  52. }
  53. }
  54. var entryId cron.EntryID
  55. entryId, _ = l.svcCtx.TimeoutCron.AddFunc("@every 1m", func() {
  56. // TODO 增加trace
  57. var timeoutTs int64
  58. if playerInfo.LastChatTs == 0 {
  59. timeoutTs = time.Now().Unix() - playerInfo.ConnectTs
  60. } else {
  61. timeoutTs = time.Now().Unix() - playerInfo.LastChatTs
  62. }
  63. if timeoutTs >= 300 {
  64. // 释放计时器任务
  65. _ = event.MustFire(globalkey.EventRemoveTimeoutJob, event.M{"entry_id": entryId})
  66. l.Logger.Infof("trigger timeout event, remove cron job, entry id: %d", entryId)
  67. // 发踢下线的command指令
  68. message, _ := sonic.MarshalString(&model.KqCmdMessage{
  69. Opt: model.CMD_CHAT_TIMEOUT,
  70. ReceiverId: in.GameId + "_" + in.PlayerId,
  71. GameId: in.GameId,
  72. Uid: in.PlayerId,
  73. })
  74. l.svcCtx.KqCmdBoxProducer.SendMessage(l.ctx, message, in.GameId+"_"+in.PlayerId)
  75. }
  76. })
  77. return &pb.InnerCsConnectPlayerResp{}, nil
  78. }