Преглед изворни кода

v0.0.1开发:inner服务开发

#Suyghur пре 2 година
родитељ
комит
6e227e6890
67 измењених фајлова са 3663 додато и 967 уклоњено
  1. 7 8
      bff/authbff/api/etc/authbff.yaml
  2. 1 1
      bff/authbff/api/internal/config/config.go
  3. 1 1
      bff/authbff/api/internal/svc/servicecontext.go
  4. 0 8
      bff/cmdbff/api/desc/bean.api
  5. 42 50
      bff/cmdbff/api/desc/cmdbff.api
  6. 5 6
      bff/cmdbff/api/etc/cmdbff.yaml
  7. 2 2
      bff/cmdbff/api/internal/config/config.go
  8. 0 25
      bff/cmdbff/api/internal/handler/csfetchmsghandler.go
  9. 0 17
      bff/cmdbff/api/internal/handler/playerfetchmsghandler.go
  10. 0 17
      bff/cmdbff/api/internal/handler/routes.go
  11. 0 41
      bff/cmdbff/api/internal/logic/csfetchmsglogic.go
  12. 0 41
      bff/cmdbff/api/internal/logic/playerfetchmsglogic.go
  13. 1 1
      bff/cmdbff/api/internal/svc/servicecontext.go
  14. 0 8
      bff/cmdbff/api/internal/types/types.go
  15. 1 7
      core/auth/rpc/etc/auth.yaml
  16. 0 16
      core/cmd/rpc/cmd/cmd.go
  17. 8 8
      core/cmd/rpc/etc/cmd.yaml
  18. 2 1
      core/cmd/rpc/internal/config/config.go
  19. 10 3
      core/cmd/rpc/internal/logic/csconnectplayerlogic.go
  20. 0 53
      core/cmd/rpc/internal/logic/csfetchmsglogic.go
  21. 6 19
      core/cmd/rpc/internal/logic/csfetchplayerqueuelogic.go
  22. 9 3
      core/cmd/rpc/internal/logic/playerdisconnectlogic.go
  23. 14 6
      core/cmd/rpc/internal/logic/playerfetchcsinfologic.go
  24. 0 54
      core/cmd/rpc/internal/logic/playerfetchmsglogic.go
  25. 2 1
      core/cmd/rpc/internal/logic/playersendmsglogic.go
  26. 0 10
      core/cmd/rpc/internal/server/cmdserver.go
  27. 6 2
      core/cmd/rpc/internal/svc/servicecontext.go
  28. 175 447
      core/cmd/rpc/pb/cmd.pb.go
  29. 0 21
      core/cmd/rpc/pb/cmd.proto
  30. 0 72
      core/cmd/rpc/pb/cmd_grpc.pb.go
  31. 21 0
      core/inner/rpc/etc/inner.yaml
  32. 39 0
      core/inner/rpc/inner.go
  33. 61 0
      core/inner/rpc/inner/inner.go
  34. 12 0
      core/inner/rpc/internal/config/config.go
  35. 12 0
      core/inner/rpc/internal/ext/global.go
  36. 71 0
      core/inner/rpc/internal/ext/sendboxhandler.go
  37. 29 0
      core/inner/rpc/internal/logic/csconnectplayerlogic.go
  38. 50 0
      core/inner/rpc/internal/logic/csfetchplayerqueuelogic.go
  39. 29 0
      core/inner/rpc/internal/logic/playerdisconnectlogic.go
  40. 35 0
      core/inner/rpc/internal/logic/playerfetchcsinfologic.go
  41. 43 0
      core/inner/rpc/internal/server/innerserver.go
  42. 67 0
      core/inner/rpc/internal/svc/servicecontext.go
  43. 702 0
      core/inner/rpc/pb/inner.pb.go
  44. 59 0
      core/inner/rpc/pb/inner.proto
  45. 213 0
      core/inner/rpc/pb/inner_grpc.pb.go
  46. 1 1
      docker-compose-env.yml
  47. 73 0
      ext/ds/rbtree/iterator.go
  48. 87 0
      ext/ds/rbtree/node.go
  49. 481 0
      ext/ds/rbtree/rbtree.go
  50. 180 0
      ext/ds/rbtree/rbtree_test.go
  51. 70 0
      ext/ds/treemap/iterator.go
  52. 193 0
      ext/ds/treemap/map.go
  53. 94 0
      ext/ds/treemap/map_test.go
  54. 153 0
      ext/ds/treemap/multimap.go
  55. 82 0
      ext/ds/treemap/multimap_test.go
  56. 13 0
      ext/model/csinfo.go
  57. 1 0
      ext/model/message.go
  58. 379 0
      ext/utils/comparator/comparator.go
  59. 64 0
      ext/utils/iterator/iterator.go
  60. 39 0
      ext/utils/sync/locker.go
  61. 9 0
      ext/utils/visitor/visitor.go
  62. 4 4
      flowsrv/rpc/etc/flowsrv.yaml
  63. 1 1
      flowsrv/rpc/internal/logic/connectlogic.go
  64. 1 1
      flowsrv/rpc/internal/logic/disconnectlogic.go
  65. 3 0
      go.mod
  66. 0 2
      go.sum
  67. 0 9
      inner/rpc/pb/inner.proto

+ 7 - 8
bff/authbff/api/etc/authbff.yaml

@@ -2,15 +2,14 @@ Name: Authbff
 Host: 0.0.0.0
 Port: 10000
 
+AuthRpcConf:
+  Endpoints:
+        - localhost:10400
+  NonBlock: true
+
 #链路追踪
 Telemetry:
   Name: authbff-api
-  Endpoint: http://ylink-jaeger-trace.ylink.svc.cluster.local:14268/api/traces
+  Endpoint: http://localhost:14268/api/traces
   Sampler: 1.0
-  Batcher: jaeger
-
-AuthRpc:
-  Etcd:
-    Hosts:
-      - ylink-etcd.ylink.svc.cluster.local:2379
-    Key: auth.rpc
+  Batcher: jaeger

+ 1 - 1
bff/authbff/api/internal/config/config.go

@@ -7,5 +7,5 @@ import (
 
 type Config struct {
 	rest.RestConf
-	AuthRpc zrpc.RpcClientConf
+	AuthRpcConf zrpc.RpcClientConf
 }

+ 1 - 1
bff/authbff/api/internal/svc/servicecontext.go

@@ -14,6 +14,6 @@ type ServiceContext struct {
 func NewServiceContext(c config.Config) *ServiceContext {
 	return &ServiceContext{
 		Config:  c,
-		AuthRpc: auth.NewAuth(zrpc.MustNewClient(c.AuthRpc)),
+		AuthRpc: auth.NewAuth(zrpc.MustNewClient(c.AuthRpcConf)),
 	}
 }

+ 0 - 8
bff/cmdbff/api/desc/bean.api

@@ -30,10 +30,6 @@ type (
         List []interface{} `json:"list"`
     }
 
-    PlayerFetchMsgResp {
-        List []interface{} `json:"list"`
-    }
-
     PlayerSendMsgReq {
         Content string `json:"content"`
         Pic string `json:"pic"`
@@ -83,10 +79,6 @@ type (
         GameId string `json:"game_id"`
     }
 
-    CsFetchMsgResp {
-        List []interface{} `json:"list"`
-    }
-
     CsSendMsgReq {
         PlayerId string `json:"player_id"`
         GameId string `json:"game_id"`

+ 42 - 50
bff/cmdbff/api/desc/cmdbff.api

@@ -1,62 +1,54 @@
 syntax = "v1"
 
 info(
-    title: "api前端服务"
-    desc: "api前端服务 "
-    author: "#Suyghur"
-    version: "v1"
+	title: "api前端服务"
+	desc: "api前端服务 "
+	author: "#Suyghur"
+	version: "v1"
 )
 
 import (
-    "bean.api"
+	"bean.api"
 )
 
 @server(
-    prefix: api/v1/cmd
-    jwt: JwtAuth
+	prefix: api/v1/cmd
+	jwt: JwtAuth
 )
 service cmdbff {
-    @doc "玩家获取客服信息"
-    @handler playerFetchCsInfo
-    post /player/fetch-cs-info (PlayerFetchCsInfoReq) returns (PlayerFetchCsInfoResp)
-
-    @doc "玩家获取历史消息"
-    @handler playerFetchHistoryMsg
-    post /player/fetch-history-msg (PlayerFetchHistoryMsgReq) returns (PlayerFetchHistoryMsgResp)
-
-    @doc "玩家获取消息"
-    @handler playerFetchMsg
-    post /player/fetch-msg returns (PlayerFetchMsgResp)
-
-    @doc "玩家发送消息"
-    @handler playerSendMsg
-    post /player/send-msg (PlayerSendMsgReq)
-
-    @doc "玩家断开连接客服"
-    @handler playerDisconnect
-    post /player/disconnect
-
-    @doc "客服获取玩家等待队列"
-    @handler csFetchPlayerQueue
-    post /cs/fetch-player-queue (CsFetchPlayerQueueReq) returns (CsFetchPlayerQueueResp)
-
-    @doc "客服连接玩家"
-    @handler csConnectPlayer
-    post /cs/connect-player (CsConnectPlayerReq)
-
-    @doc "客服获取历史会话列表"
-    @handler csFetchHistoryList
-    post /cs/fetch-history-list (CsFetchHistoryChatReq) returns (CsFetchHistoryChatResp)
-
-    @doc "客服获取历史消息"
-    @handler csFetchHistoryMsg
-    post /cs/fetch-history-msg (CsFetchHistoryMsgReq) returns (CsFetchHistoryMsgResp)
-
-    @doc "客服获取消息"
-    @handler csFetchMsg
-    post /cs/fetch-msg (CsFetchMsgReq) returns (CsFetchMsgResp)
-
-    @doc "客服发送消息"
-    @handler csSendMsg
-    post /cs/send-msg (CsSendMsgReq)
+	@doc "玩家获取客服信息"
+	@handler playerFetchCsInfo
+	post /player/fetch-cs-info (PlayerFetchCsInfoReq) returns (PlayerFetchCsInfoResp)
+	
+	@doc "玩家获取历史消息"
+	@handler playerFetchHistoryMsg
+	post /player/fetch-history-msg (PlayerFetchHistoryMsgReq) returns (PlayerFetchHistoryMsgResp)
+	
+	@doc "玩家发送消息"
+	@handler playerSendMsg
+	post /player/send-msg (PlayerSendMsgReq)
+	
+	@doc "玩家断开连接客服"
+	@handler playerDisconnect
+	post /player/disconnect
+	
+	@doc "客服获取玩家等待队列"
+	@handler csFetchPlayerQueue
+	post /cs/fetch-player-queue (CsFetchPlayerQueueReq) returns (CsFetchPlayerQueueResp)
+	
+	@doc "客服连接玩家"
+	@handler csConnectPlayer
+	post /cs/connect-player (CsConnectPlayerReq)
+	
+	@doc "客服获取历史会话列表"
+	@handler csFetchHistoryList
+	post /cs/fetch-history-list (CsFetchHistoryChatReq) returns (CsFetchHistoryChatResp)
+	
+	@doc "客服获取历史消息"
+	@handler csFetchHistoryMsg
+	post /cs/fetch-history-msg (CsFetchHistoryMsgReq) returns (CsFetchHistoryMsgResp)
+	
+	@doc "客服发送消息"
+	@handler csSendMsg
+	post /cs/send-msg (CsSendMsgReq)
 }

+ 5 - 6
bff/cmdbff/api/etc/cmdbff.yaml

@@ -4,15 +4,14 @@ Port: 10100
 
 Telemetry:
   Name: cmdbff-api
-  Endpoint: http://127.0.0.1:14268/api/traces
+  Endpoint: http://localhost:14268/api/traces
   Sampler: 1.0
   Batcher: jaeger
 
-CmdRpc:
-  Etcd:
-    Hosts:
-      - 127.0.0.1:2379
-    Key: cmd.rpc
+CmdRpcConf:
+  Endpoints:
+    - localhost:10300
+  NonBlock: true
 
 JwtAuth:
   AccessSecret: ylink2022

+ 2 - 2
bff/cmdbff/api/internal/config/config.go

@@ -7,9 +7,9 @@ import (
 
 type Config struct {
 	rest.RestConf
-	JwtAuth struct {
+	CmdRpcConf zrpc.RpcClientConf
+	JwtAuth    struct {
 		AccessSecret string
 		AccessExpire int64
 	}
-	CmdRpc zrpc.RpcClientConf
 }

+ 0 - 25
bff/cmdbff/api/internal/handler/csfetchmsghandler.go

@@ -1,25 +0,0 @@
-package handler
-
-import (
-	"net/http"
-	"ylink/ext/result"
-
-	"github.com/zeromicro/go-zero/rest/httpx"
-	"ylink/bff/cmdbff/api/internal/logic"
-	"ylink/bff/cmdbff/api/internal/svc"
-	"ylink/bff/cmdbff/api/internal/types"
-)
-
-func csFetchMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		var req types.CsFetchMsgReq
-		if err := httpx.Parse(r, &req); err != nil {
-			result.ParamErrorResult(r, w, err)
-			return
-		}
-
-		l := logic.NewCsFetchMsgLogic(r.Context(), svcCtx)
-		resp, err := l.CsFetchMsg(&req)
-		result.HttpResult(r, w, resp, err)
-	}
-}

+ 0 - 17
bff/cmdbff/api/internal/handler/playerfetchmsghandler.go

@@ -1,17 +0,0 @@
-package handler
-
-import (
-	"net/http"
-	"ylink/ext/result"
-
-	"ylink/bff/cmdbff/api/internal/logic"
-	"ylink/bff/cmdbff/api/internal/svc"
-)
-
-func playerFetchMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
-	return func(w http.ResponseWriter, r *http.Request) {
-		l := logic.NewPlayerFetchMsgLogic(r.Context(), svcCtx)
-		resp, err := l.PlayerFetchMsg()
-		result.HttpResult(r, w, resp, err)
-	}
-}

+ 0 - 17
bff/cmdbff/api/internal/handler/routes.go

@@ -22,11 +22,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/player/fetch-history-msg",
 				Handler: playerFetchHistoryMsgHandler(serverCtx),
 			},
-			{
-				Method:  http.MethodPost,
-				Path:    "/player/fetch-msg",
-				Handler: playerFetchMsgHandler(serverCtx),
-			},
 			{
 				Method:  http.MethodPost,
 				Path:    "/player/send-msg",
@@ -37,13 +32,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/player/disconnect",
 				Handler: playerDisconnectHandler(serverCtx),
 			},
-		},
-		rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
-		rest.WithPrefix("/api/v1/cmd"),
-	)
-
-	server.AddRoutes(
-		[]rest.Route{
 			{
 				Method:  http.MethodPost,
 				Path:    "/cs/fetch-player-queue",
@@ -64,11 +52,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/cs/fetch-history-msg",
 				Handler: csFetchHistoryMsgHandler(serverCtx),
 			},
-			{
-				Method:  http.MethodPost,
-				Path:    "/cs/fetch-msg",
-				Handler: csFetchMsgHandler(serverCtx),
-			},
 			{
 				Method:  http.MethodPost,
 				Path:    "/cs/send-msg",

+ 0 - 41
bff/cmdbff/api/internal/logic/csfetchmsglogic.go

@@ -1,41 +0,0 @@
-package logic
-
-import (
-	"context"
-	"ylink/core/cmd/rpc/cmd"
-	"ylink/ext/ctxdata"
-
-	"ylink/bff/cmdbff/api/internal/svc"
-	"ylink/bff/cmdbff/api/internal/types"
-
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type CsFetchMsgLogic struct {
-	logx.Logger
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-}
-
-func NewCsFetchMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CsFetchMsgLogic {
-	return &CsFetchMsgLogic{
-		Logger: logx.WithContext(ctx),
-		ctx:    ctx,
-		svcCtx: svcCtx,
-	}
-}
-
-func (l *CsFetchMsgLogic) CsFetchMsg(req *types.CsFetchMsgReq) (resp *types.CsFetchMsgResp, err error) {
-	csId := ctxdata.GetCsIdFromCtx(l.ctx)
-	cmdResp, err := l.svcCtx.CmdRpc.CsFetchMsg(l.ctx, &cmd.CsFetchMsgReq{
-		CsId:     csId,
-		PlayerId: req.PlayerId,
-		GameId:   req.GameId,
-	})
-	if err != nil {
-		return nil, err
-	}
-	return &types.CsFetchMsgResp{
-		List: cmdResp.List.AsSlice(),
-	}, nil
-}

+ 0 - 41
bff/cmdbff/api/internal/logic/playerfetchmsglogic.go

@@ -1,41 +0,0 @@
-package logic
-
-import (
-	"context"
-	"ylink/core/cmd/rpc/pb"
-	"ylink/ext/ctxdata"
-
-	"ylink/bff/cmdbff/api/internal/svc"
-	"ylink/bff/cmdbff/api/internal/types"
-
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type PlayerFetchMsgLogic struct {
-	logx.Logger
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-}
-
-func NewPlayerFetchMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PlayerFetchMsgLogic {
-	return &PlayerFetchMsgLogic{
-		Logger: logx.WithContext(ctx),
-		ctx:    ctx,
-		svcCtx: svcCtx,
-	}
-}
-
-func (l *PlayerFetchMsgLogic) PlayerFetchMsg() (resp *types.PlayerFetchMsgResp, err error) {
-	playerId := ctxdata.GetGameIdFromCtx(l.ctx)
-	gameId := ctxdata.GetGameIdFromCtx(l.ctx)
-	cmdResp, err := l.svcCtx.CmdRpc.PlayerFetchMsg(l.ctx, &pb.PlayerFetchMsgReq{
-		PlayerId: playerId,
-		GameId:   gameId,
-	})
-	if err != nil {
-		return nil, err
-	}
-	return &types.PlayerFetchMsgResp{
-		List: cmdResp.List.AsSlice(),
-	}, nil
-}

+ 1 - 1
bff/cmdbff/api/internal/svc/servicecontext.go

@@ -14,6 +14,6 @@ type ServiceContext struct {
 func NewServiceContext(c config.Config) *ServiceContext {
 	return &ServiceContext{
 		Config: c,
-		CmdRpc: cmd.NewCmd(zrpc.MustNewClient(c.CmdRpc)),
+		CmdRpc: cmd.NewCmd(zrpc.MustNewClient(c.CmdRpcConf)),
 	}
 }

+ 0 - 8
bff/cmdbff/api/internal/types/types.go

@@ -24,10 +24,6 @@ type PlayerFetchHistoryMsgResp struct {
 	List        []interface{} `json:"list"`
 }
 
-type PlayerFetchMsgResp struct {
-	List []interface{} `json:"list"`
-}
-
 type PlayerSendMsgReq struct {
 	Content string `json:"content"`
 	Pic     string `json:"pic"`
@@ -75,10 +71,6 @@ type CsFetchMsgReq struct {
 	GameId   string `json:"game_id"`
 }
 
-type CsFetchMsgResp struct {
-	List []interface{} `json:"list"`
-}
-
 type CsSendMsgReq struct {
 	PlayerId string `json:"player_id"`
 	GameId   string `json:"game_id"`

+ 1 - 7
core/auth/rpc/etc/auth.yaml

@@ -1,15 +1,9 @@
 Name: auth.rpc
 ListenOn: 0.0.0.0:10400
 
-Etcd:
-  Hosts:
-    - ylink-etcd.ylink.svc.cluster.local:2379
-  Key: auth.rpc
-
-
 Telemetry:
   Name: auth-rpc
-  Endpoint: http://ylink-jaeger-trace.ylink.svc.cluster.local:14268/api/traces
+  Endpoint: http://localhost:14268/api/traces
   Sampler: 1.0
   Batcher: jaeger
 

+ 0 - 16
core/cmd/rpc/cmd/cmd.go

@@ -19,8 +19,6 @@ type (
 	CsFetchHistoryChatResp    = pb.CsFetchHistoryChatResp
 	CsFetchHistoryMsgReq      = pb.CsFetchHistoryMsgReq
 	CsFetchHistoryMsgResp     = pb.CsFetchHistoryMsgResp
-	CsFetchMsgReq             = pb.CsFetchMsgReq
-	CsFetchMsgResp            = pb.CsFetchMsgResp
 	CsFetchPlayerQueueReq     = pb.CsFetchPlayerQueueReq
 	CsFetchPlayerQueueResp    = pb.CsFetchPlayerQueueResp
 	CsSendMsgReq              = pb.CsSendMsgReq
@@ -31,22 +29,18 @@ type (
 	PlayerFetchCsInfoResp     = pb.PlayerFetchCsInfoResp
 	PlayerFetchHistoryMsgReq  = pb.PlayerFetchHistoryMsgReq
 	PlayerFetchHistoryMsgResp = pb.PlayerFetchHistoryMsgResp
-	PlayerFetchMsgReq         = pb.PlayerFetchMsgReq
-	PlayerFetchMsgResp        = pb.PlayerFetchMsgResp
 	PlayerSendMsgReq          = pb.PlayerSendMsgReq
 	PlayerSendMsgResp         = pb.PlayerSendMsgResp
 
 	Cmd interface {
 		PlayerFetchCsInfo(ctx context.Context, in *PlayerFetchCsInfoReq, opts ...grpc.CallOption) (*PlayerFetchCsInfoResp, error)
 		PlayerFetchHistoryMsg(ctx context.Context, in *PlayerFetchHistoryMsgReq, opts ...grpc.CallOption) (*PlayerFetchHistoryMsgResp, error)
-		PlayerFetchMsg(ctx context.Context, in *PlayerFetchMsgReq, opts ...grpc.CallOption) (*PlayerFetchMsgResp, error)
 		PlayerSendMsg(ctx context.Context, in *PlayerSendMsgReq, opts ...grpc.CallOption) (*PlayerSendMsgResp, error)
 		PlayerDisconnect(ctx context.Context, in *PlayerDisconnectReq, opts ...grpc.CallOption) (*PlayerDisconnectResp, error)
 		CsFetchPlayerQueue(ctx context.Context, in *CsFetchPlayerQueueReq, opts ...grpc.CallOption) (*CsFetchPlayerQueueResp, error)
 		CsConnectPlayer(ctx context.Context, in *CsConnectPlayerReq, opts ...grpc.CallOption) (*CsConnectPlayerResp, error)
 		CsFetchHistoryChat(ctx context.Context, in *CsFetchHistoryChatReq, opts ...grpc.CallOption) (*CsFetchHistoryChatResp, error)
 		CsFetchHistoryMsg(ctx context.Context, in *CsFetchHistoryMsgReq, opts ...grpc.CallOption) (*CsFetchHistoryMsgResp, error)
-		CsFetchMsg(ctx context.Context, in *CsFetchMsgReq, opts ...grpc.CallOption) (*CsFetchMsgResp, error)
 		CsSendMsg(ctx context.Context, in *CsSendMsgReq, opts ...grpc.CallOption) (*CsSendMsgResp, error)
 	}
 
@@ -71,11 +65,6 @@ func (m *defaultCmd) PlayerFetchHistoryMsg(ctx context.Context, in *PlayerFetchH
 	return client.PlayerFetchHistoryMsg(ctx, in, opts...)
 }
 
-func (m *defaultCmd) PlayerFetchMsg(ctx context.Context, in *PlayerFetchMsgReq, opts ...grpc.CallOption) (*PlayerFetchMsgResp, error) {
-	client := pb.NewCmdClient(m.cli.Conn())
-	return client.PlayerFetchMsg(ctx, in, opts...)
-}
-
 func (m *defaultCmd) PlayerSendMsg(ctx context.Context, in *PlayerSendMsgReq, opts ...grpc.CallOption) (*PlayerSendMsgResp, error) {
 	client := pb.NewCmdClient(m.cli.Conn())
 	return client.PlayerSendMsg(ctx, in, opts...)
@@ -106,11 +95,6 @@ func (m *defaultCmd) CsFetchHistoryMsg(ctx context.Context, in *CsFetchHistoryMs
 	return client.CsFetchHistoryMsg(ctx, in, opts...)
 }
 
-func (m *defaultCmd) CsFetchMsg(ctx context.Context, in *CsFetchMsgReq, opts ...grpc.CallOption) (*CsFetchMsgResp, error) {
-	client := pb.NewCmdClient(m.cli.Conn())
-	return client.CsFetchMsg(ctx, in, opts...)
-}
-
 func (m *defaultCmd) CsSendMsg(ctx context.Context, in *CsSendMsgReq, opts ...grpc.CallOption) (*CsSendMsgResp, error) {
 	client := pb.NewCmdClient(m.cli.Conn())
 	return client.CsSendMsg(ctx, in, opts...)

+ 8 - 8
core/cmd/rpc/etc/cmd.yaml

@@ -1,21 +1,21 @@
 Name: cmd.rpc
 ListenOn: 0.0.0.0:10300
 
-Etcd:
-  Hosts:
-    - 127.0.0.1:2379
-  Key: cmd.rpc
+InnerRpcConf:
+  Endpoints:
+    - localhost:10500
+  NonBlock: true
 
 Telemetry:
   Name: cmd-rpc
-  Endpoint: http://127.0.0.1:14268/api/traces
+  Endpoint: http://localhost:14268/api/traces
   Sampler: 1.0
   Batcher: jaeger
 
-KqChatMsgConf:
+KqSendMsgConf:
   Brokers:
-    - 127.0.0.1:9092
-  Topic: chat-msg-topic
+    - localhost:9092
+  Topic: send-box-topic
   GroupId:
 
 Redis:

+ 2 - 1
core/cmd/rpc/internal/config/config.go

@@ -7,5 +7,6 @@ import (
 
 type Config struct {
 	zrpc.RpcServerConf
-	KqChatMsgConf kafka.KqConfig
+	InnerRpcConf  zrpc.RpcClientConf
+	KqSendMsgConf kafka.KqConfig
 }

+ 10 - 3
core/cmd/rpc/internal/logic/csconnectplayerlogic.go

@@ -2,9 +2,9 @@ package logic
 
 import (
 	"context"
-
 	"ylink/core/cmd/rpc/internal/svc"
 	"ylink/core/cmd/rpc/pb"
+	"ylink/core/inner/rpc/inner"
 
 	"github.com/zeromicro/go-zero/core/logx"
 )
@@ -24,8 +24,15 @@ func NewCsConnectPlayerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *C
 }
 
 func (l *CsConnectPlayerLogic) CsConnectPlayer(in *pb.CsConnectPlayerReq) (*pb.CsConnectPlayerResp, error) {
-	// todo 调用inner修改状态,如果玩家在等待队列中,则取出玩家
-	// todo 建立连接的映射关系
+	// 调用inner服务建立映射关系
+	_, err := l.svcCtx.InnerRpc.CsConnectPlayer(l.ctx, &inner.InnerCsConnectPlayerReq{
+		CsId:     in.CsId,
+		PlayerId: in.PlayerId,
+		GameId:   in.GameId,
+	})
+	if err != nil {
+		return nil, err
+	}
 
 	return &pb.CsConnectPlayerResp{}, nil
 }

+ 0 - 53
core/cmd/rpc/internal/logic/csfetchmsglogic.go

@@ -1,53 +0,0 @@
-package logic
-
-import (
-	"context"
-	"github.com/pkg/errors"
-	"google.golang.org/protobuf/types/known/structpb"
-	"ylink/ext/result"
-
-	"ylink/core/cmd/rpc/internal/svc"
-	"ylink/core/cmd/rpc/pb"
-
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type CsFetchMsgLogic struct {
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-	logx.Logger
-}
-
-func NewCsFetchMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CsFetchMsgLogic {
-	return &CsFetchMsgLogic{
-		ctx:    ctx,
-		svcCtx: svcCtx,
-		Logger: logx.WithContext(ctx),
-	}
-}
-
-func (l *CsFetchMsgLogic) CsFetchMsg(in *pb.CsFetchMsgReq) (*pb.CsFetchMsgResp, error) {
-	// todo 查询自己收件箱下对应玩家的信息
-	list, err := structpb.NewList([]interface{}{
-		map[string]interface{}{
-			"content":     "你好呀,我是玩家",
-			"pic":         "https://www.baidu.com",
-			"send_id":     in.PlayerId,
-			"receiver_id": in.CsId,
-			"create_time": "2022-04-27 14:47:50",
-		},
-		map[string]interface{}{
-			"content":     "有个问题需要帮忙处理一下",
-			"pic":         "",
-			"send_id":     in.PlayerId,
-			"receiver_id": in.CsId,
-			"create_time": "2022-04-27 14:47:50",
-		},
-	})
-	if err != nil {
-		return nil, errors.Wrap(result.NewErrMsg("fetch cs message list error"), "")
-	}
-	return &pb.CsFetchMsgResp{
-		List: list,
-	}, nil
-}

+ 6 - 19
core/cmd/rpc/internal/logic/csfetchplayerqueuelogic.go

@@ -2,12 +2,9 @@ package logic
 
 import (
 	"context"
-	"github.com/pkg/errors"
-	"google.golang.org/protobuf/types/known/structpb"
-	"ylink/ext/result"
-
 	"ylink/core/cmd/rpc/internal/svc"
 	"ylink/core/cmd/rpc/pb"
+	"ylink/core/inner/rpc/inner"
 
 	"github.com/zeromicro/go-zero/core/logx"
 )
@@ -27,24 +24,14 @@ func NewCsFetchPlayerQueueLogic(ctx context.Context, svcCtx *svc.ServiceContext)
 }
 
 func (l *CsFetchPlayerQueueLogic) CsFetchPlayerQueue(in *pb.CsFetchPlayerQueueReq) (*pb.CsFetchPlayerQueueResp, error) {
-	// todo 查询等待用户的队列
-
-	list, err := structpb.NewList([]interface{}{
-		map[string]interface{}{
-			"player_id": "player1111",
-			"game_id":   "game1231",
-			"wait_time": 1000,
-		},
-		map[string]interface{}{
-			"player_id": "player2222",
-			"game_id":   "game1231",
-			"wait_time": 10,
-		},
+	// 调用inner服务查询等待用户的队列
+	innerResp, err := l.svcCtx.InnerRpc.CsFetchPlayerQueue(l.ctx, &inner.InnerCsFetchPlayerQueueReq{
+		Limit: in.Limit,
 	})
 	if err != nil {
-		return nil, errors.Wrap(result.NewErrMsg("fetch player wait queue error"), "")
+		return nil, err
 	}
 	return &pb.CsFetchPlayerQueueResp{
-		List: list,
+		List: innerResp.List,
 	}, nil
 }

+ 9 - 3
core/cmd/rpc/internal/logic/playerdisconnectlogic.go

@@ -2,9 +2,9 @@ package logic
 
 import (
 	"context"
-
 	"ylink/core/cmd/rpc/internal/svc"
 	"ylink/core/cmd/rpc/pb"
+	"ylink/core/inner/rpc/inner"
 
 	"github.com/zeromicro/go-zero/core/logx"
 )
@@ -24,7 +24,13 @@ func NewPlayerDisconnectLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
 }
 
 func (l *PlayerDisconnectLogic) PlayerDisconnect(in *pb.PlayerDisconnectReq) (*pb.PlayerDisconnectResp, error) {
-	// todo 修改inner服务玩家状态
-
+	// 调用inner服务玩家状态
+	_, err := l.svcCtx.InnerRpc.PlayerDisconnect(l.ctx, &inner.InnerPlayerDisconnectReq{
+		PlayerId: in.PlayerId,
+		GameId:   in.GameId,
+	})
+	if err != nil {
+		return nil, err
+	}
 	return &pb.PlayerDisconnectResp{}, nil
 }

+ 14 - 6
core/cmd/rpc/internal/logic/playerfetchcsinfologic.go

@@ -2,9 +2,9 @@ package logic
 
 import (
 	"context"
-
 	"ylink/core/cmd/rpc/internal/svc"
 	"ylink/core/cmd/rpc/pb"
+	"ylink/core/inner/rpc/inner"
 
 	"github.com/zeromicro/go-zero/core/logx"
 )
@@ -24,11 +24,19 @@ func NewPlayerFetchCsInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext)
 }
 
 func (l *PlayerFetchCsInfoLogic) PlayerFetchCsInfo(in *pb.PlayerFetchCsInfoReq) (*pb.PlayerFetchCsInfoResp, error) {
+	innerResp, err := l.svcCtx.InnerRpc.PlayerFetchCsInfo(l.ctx, &inner.InnerPlayerFetchCsInfoReq{
+		PlayerId: in.PlayerId,
+		GameId:   in.GameId,
+		CsId:     in.CsId,
+	})
+	if err != nil {
+		return nil, err
+	}
 	return &pb.PlayerFetchCsInfoResp{
-		CsId:         in.CsId,
-		CsNickname:   "vip客服1231",
-		CsAvatarUrl:  "https://www.baiduc.om",
-		CsSignature:  "服务时间:9:30-20:30",
-		OnlineStatus: 1,
+		CsId:         innerResp.CsId,
+		CsNickname:   innerResp.CsNickname,
+		CsAvatarUrl:  innerResp.CsAvatarUrl,
+		CsSignature:  innerResp.CsSignature,
+		OnlineStatus: innerResp.OnlineStatus,
 	}, nil
 }

+ 0 - 54
core/cmd/rpc/internal/logic/playerfetchmsglogic.go

@@ -1,54 +0,0 @@
-package logic
-
-import (
-	"context"
-	"github.com/pkg/errors"
-	"google.golang.org/protobuf/types/known/structpb"
-	"ylink/ext/result"
-
-	"ylink/core/cmd/rpc/internal/svc"
-	"ylink/core/cmd/rpc/pb"
-
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type PlayerFetchMsgLogic struct {
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-	logx.Logger
-}
-
-func NewPlayerFetchMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PlayerFetchMsgLogic {
-	return &PlayerFetchMsgLogic{
-		ctx:    ctx,
-		svcCtx: svcCtx,
-		Logger: logx.WithContext(ctx),
-	}
-}
-
-func (l *PlayerFetchMsgLogic) PlayerFetchMsg(in *pb.PlayerFetchMsgReq) (*pb.PlayerFetchMsgResp, error) {
-	// todo 全量取出自己收件箱下的信息
-	list, err := structpb.NewList([]interface{}{
-		map[string]interface{}{
-			"content":     "你好呀,我是玩家",
-			"pic":         "https://www.baidu.com",
-			"send_id":     in.PlayerId,
-			"receiver_id": "cs1231",
-			"create_time": "2022-04-27 14:47:50",
-		},
-		map[string]interface{}{
-			"content":     "你好呀,我是客服",
-			"pic":         "",
-			"send_id":     "cs1231",
-			"receiver_id": in.PlayerId,
-			"create_time": "2022-04-27 14:47:50",
-		},
-	})
-	if err != nil {
-		return nil, errors.Wrap(result.NewErrMsg("fetch message list error"), "")
-	}
-
-	return &pb.PlayerFetchMsgResp{
-		List: list,
-	}, nil
-}

+ 2 - 1
core/cmd/rpc/internal/logic/playersendmsglogic.go

@@ -33,8 +33,9 @@ func (l *PlayerSendMsgLogic) PlayerSendMsg(in *pb.PlayerSendMsgReq) (*pb.PlayerS
 		Pic:        in.Pic,
 		ReceiverId: "",
 		SenderId:   in.PlayerId,
+		GameId:     in.GameId,
 	})
-	_, _, err := l.svcCtx.ChatMsgProducer.SendMessage(string(msg), in.PlayerId)
+	_, _, err := l.svcCtx.SendBoxProducer.SendMessage(string(msg), in.PlayerId)
 	if err != nil {
 		return nil, err
 	}

+ 0 - 10
core/cmd/rpc/internal/server/cmdserver.go

@@ -32,11 +32,6 @@ func (s *CmdServer) PlayerFetchHistoryMsg(ctx context.Context, in *pb.PlayerFetc
 	return l.PlayerFetchHistoryMsg(in)
 }
 
-func (s *CmdServer) PlayerFetchMsg(ctx context.Context, in *pb.PlayerFetchMsgReq) (*pb.PlayerFetchMsgResp, error) {
-	l := logic.NewPlayerFetchMsgLogic(ctx, s.svcCtx)
-	return l.PlayerFetchMsg(in)
-}
-
 func (s *CmdServer) PlayerSendMsg(ctx context.Context, in *pb.PlayerSendMsgReq) (*pb.PlayerSendMsgResp, error) {
 	l := logic.NewPlayerSendMsgLogic(ctx, s.svcCtx)
 	return l.PlayerSendMsg(in)
@@ -67,11 +62,6 @@ func (s *CmdServer) CsFetchHistoryMsg(ctx context.Context, in *pb.CsFetchHistory
 	return l.CsFetchHistoryMsg(in)
 }
 
-func (s *CmdServer) CsFetchMsg(ctx context.Context, in *pb.CsFetchMsgReq) (*pb.CsFetchMsgResp, error) {
-	l := logic.NewCsFetchMsgLogic(ctx, s.svcCtx)
-	return l.CsFetchMsg(in)
-}
-
 func (s *CmdServer) CsSendMsg(ctx context.Context, in *pb.CsSendMsgReq) (*pb.CsSendMsgResp, error) {
 	l := logic.NewCsSendMsgLogic(ctx, s.svcCtx)
 	return l.CsSendMsg(in)

+ 6 - 2
core/cmd/rpc/internal/svc/servicecontext.go

@@ -2,20 +2,24 @@ package svc
 
 import (
 	"github.com/zeromicro/go-zero/core/stores/redis"
+	"github.com/zeromicro/go-zero/zrpc"
 	"ylink/core/cmd/rpc/internal/config"
+	"ylink/core/inner/rpc/inner"
 	"ylink/ext/kafka"
 )
 
 type ServiceContext struct {
 	Config          config.Config
-	ChatMsgProducer *kafka.Producer
+	InnerRpc        inner.Inner
+	SendBoxProducer *kafka.Producer
 	RedisClient     *redis.Redis
 }
 
 func NewServiceContext(c config.Config) *ServiceContext {
 	return &ServiceContext{
 		Config:          c,
-		ChatMsgProducer: kafka.NewKafkaProducer(c.KqChatMsgConf.Brokers, c.KqChatMsgConf.Topic),
+		InnerRpc:        inner.NewInner(zrpc.MustNewClient(c.InnerRpcConf)),
+		SendBoxProducer: kafka.NewKafkaProducer(c.KqSendMsgConf.Brokers, c.KqSendMsgConf.Topic),
 		RedisClient: redis.New(c.Redis.Host, func(r *redis.Redis) {
 			r.Type = c.Redis.Type
 			r.Pass = c.Redis.Pass

Разлика између датотеке није приказан због своје велике величине
+ 175 - 447
core/cmd/rpc/pb/cmd.pb.go


+ 0 - 21
core/cmd/rpc/pb/cmd.proto

@@ -36,15 +36,6 @@ message PlayerFetchHistoryMsgResp{
   google.protobuf.ListValue list = 3;
 }
 
-message PlayerFetchMsgReq{
-  string player_id = 1;
-  string game_id = 2;
-}
-
-message PlayerFetchMsgResp{
-  google.protobuf.ListValue list = 1;
-}
-
 message PlayerSendMsgReq{
   string player_id = 1;
   string game_id = 2;
@@ -108,16 +99,6 @@ message CsFetchHistoryMsgResp{
   google.protobuf.ListValue list = 4;
 }
 
-message CsFetchMsgReq{
-  string cs_id = 1;
-  string player_id = 2;
-  string game_id = 3;
-}
-
-message CsFetchMsgResp{
-  google.protobuf.ListValue list = 4;
-}
-
 message CsSendMsgReq{
   string cs_id = 1;
   string player_id = 2;
@@ -131,7 +112,6 @@ message CsSendMsgResp{}
 service Cmd {
   rpc playerFetchCsInfo (PlayerFetchCsInfoReq) returns (PlayerFetchCsInfoResp);
   rpc playerFetchHistoryMsg (PlayerFetchHistoryMsgReq) returns (PlayerFetchHistoryMsgResp);
-  rpc playerFetchMsg (PlayerFetchMsgReq) returns (PlayerFetchMsgResp);
   rpc playerSendMsg (PlayerSendMsgReq) returns (PlayerSendMsgResp);
   rpc playerDisconnect (PlayerDisconnectReq) returns (PlayerDisconnectResp);
 
@@ -139,6 +119,5 @@ service Cmd {
   rpc csConnectPlayer (CsConnectPlayerReq) returns (CsConnectPlayerResp);
   rpc csFetchHistoryChat (CsFetchHistoryChatReq) returns (CsFetchHistoryChatResp);
   rpc csFetchHistoryMsg (CsFetchHistoryMsgReq) returns (CsFetchHistoryMsgResp);
-  rpc csFetchMsg (CsFetchMsgReq) returns (CsFetchMsgResp);
   rpc csSendMsg (CsSendMsgReq) returns (CsSendMsgResp);
 }

+ 0 - 72
core/cmd/rpc/pb/cmd_grpc.pb.go

@@ -24,14 +24,12 @@ const _ = grpc.SupportPackageIsVersion7
 type CmdClient interface {
 	PlayerFetchCsInfo(ctx context.Context, in *PlayerFetchCsInfoReq, opts ...grpc.CallOption) (*PlayerFetchCsInfoResp, error)
 	PlayerFetchHistoryMsg(ctx context.Context, in *PlayerFetchHistoryMsgReq, opts ...grpc.CallOption) (*PlayerFetchHistoryMsgResp, error)
-	PlayerFetchMsg(ctx context.Context, in *PlayerFetchMsgReq, opts ...grpc.CallOption) (*PlayerFetchMsgResp, error)
 	PlayerSendMsg(ctx context.Context, in *PlayerSendMsgReq, opts ...grpc.CallOption) (*PlayerSendMsgResp, error)
 	PlayerDisconnect(ctx context.Context, in *PlayerDisconnectReq, opts ...grpc.CallOption) (*PlayerDisconnectResp, error)
 	CsFetchPlayerQueue(ctx context.Context, in *CsFetchPlayerQueueReq, opts ...grpc.CallOption) (*CsFetchPlayerQueueResp, error)
 	CsConnectPlayer(ctx context.Context, in *CsConnectPlayerReq, opts ...grpc.CallOption) (*CsConnectPlayerResp, error)
 	CsFetchHistoryChat(ctx context.Context, in *CsFetchHistoryChatReq, opts ...grpc.CallOption) (*CsFetchHistoryChatResp, error)
 	CsFetchHistoryMsg(ctx context.Context, in *CsFetchHistoryMsgReq, opts ...grpc.CallOption) (*CsFetchHistoryMsgResp, error)
-	CsFetchMsg(ctx context.Context, in *CsFetchMsgReq, opts ...grpc.CallOption) (*CsFetchMsgResp, error)
 	CsSendMsg(ctx context.Context, in *CsSendMsgReq, opts ...grpc.CallOption) (*CsSendMsgResp, error)
 }
 
@@ -61,15 +59,6 @@ func (c *cmdClient) PlayerFetchHistoryMsg(ctx context.Context, in *PlayerFetchHi
 	return out, nil
 }
 
-func (c *cmdClient) PlayerFetchMsg(ctx context.Context, in *PlayerFetchMsgReq, opts ...grpc.CallOption) (*PlayerFetchMsgResp, error) {
-	out := new(PlayerFetchMsgResp)
-	err := c.cc.Invoke(ctx, "/pb.Cmd/playerFetchMsg", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
 func (c *cmdClient) PlayerSendMsg(ctx context.Context, in *PlayerSendMsgReq, opts ...grpc.CallOption) (*PlayerSendMsgResp, error) {
 	out := new(PlayerSendMsgResp)
 	err := c.cc.Invoke(ctx, "/pb.Cmd/playerSendMsg", in, out, opts...)
@@ -124,15 +113,6 @@ func (c *cmdClient) CsFetchHistoryMsg(ctx context.Context, in *CsFetchHistoryMsg
 	return out, nil
 }
 
-func (c *cmdClient) CsFetchMsg(ctx context.Context, in *CsFetchMsgReq, opts ...grpc.CallOption) (*CsFetchMsgResp, error) {
-	out := new(CsFetchMsgResp)
-	err := c.cc.Invoke(ctx, "/pb.Cmd/csFetchMsg", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
 func (c *cmdClient) CsSendMsg(ctx context.Context, in *CsSendMsgReq, opts ...grpc.CallOption) (*CsSendMsgResp, error) {
 	out := new(CsSendMsgResp)
 	err := c.cc.Invoke(ctx, "/pb.Cmd/csSendMsg", in, out, opts...)
@@ -148,14 +128,12 @@ func (c *cmdClient) CsSendMsg(ctx context.Context, in *CsSendMsgReq, opts ...grp
 type CmdServer interface {
 	PlayerFetchCsInfo(context.Context, *PlayerFetchCsInfoReq) (*PlayerFetchCsInfoResp, error)
 	PlayerFetchHistoryMsg(context.Context, *PlayerFetchHistoryMsgReq) (*PlayerFetchHistoryMsgResp, error)
-	PlayerFetchMsg(context.Context, *PlayerFetchMsgReq) (*PlayerFetchMsgResp, error)
 	PlayerSendMsg(context.Context, *PlayerSendMsgReq) (*PlayerSendMsgResp, error)
 	PlayerDisconnect(context.Context, *PlayerDisconnectReq) (*PlayerDisconnectResp, error)
 	CsFetchPlayerQueue(context.Context, *CsFetchPlayerQueueReq) (*CsFetchPlayerQueueResp, error)
 	CsConnectPlayer(context.Context, *CsConnectPlayerReq) (*CsConnectPlayerResp, error)
 	CsFetchHistoryChat(context.Context, *CsFetchHistoryChatReq) (*CsFetchHistoryChatResp, error)
 	CsFetchHistoryMsg(context.Context, *CsFetchHistoryMsgReq) (*CsFetchHistoryMsgResp, error)
-	CsFetchMsg(context.Context, *CsFetchMsgReq) (*CsFetchMsgResp, error)
 	CsSendMsg(context.Context, *CsSendMsgReq) (*CsSendMsgResp, error)
 	mustEmbedUnimplementedCmdServer()
 }
@@ -170,9 +148,6 @@ func (UnimplementedCmdServer) PlayerFetchCsInfo(context.Context, *PlayerFetchCsI
 func (UnimplementedCmdServer) PlayerFetchHistoryMsg(context.Context, *PlayerFetchHistoryMsgReq) (*PlayerFetchHistoryMsgResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method PlayerFetchHistoryMsg not implemented")
 }
-func (UnimplementedCmdServer) PlayerFetchMsg(context.Context, *PlayerFetchMsgReq) (*PlayerFetchMsgResp, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method PlayerFetchMsg not implemented")
-}
 func (UnimplementedCmdServer) PlayerSendMsg(context.Context, *PlayerSendMsgReq) (*PlayerSendMsgResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method PlayerSendMsg not implemented")
 }
@@ -191,9 +166,6 @@ func (UnimplementedCmdServer) CsFetchHistoryChat(context.Context, *CsFetchHistor
 func (UnimplementedCmdServer) CsFetchHistoryMsg(context.Context, *CsFetchHistoryMsgReq) (*CsFetchHistoryMsgResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method CsFetchHistoryMsg not implemented")
 }
-func (UnimplementedCmdServer) CsFetchMsg(context.Context, *CsFetchMsgReq) (*CsFetchMsgResp, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method CsFetchMsg not implemented")
-}
 func (UnimplementedCmdServer) CsSendMsg(context.Context, *CsSendMsgReq) (*CsSendMsgResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method CsSendMsg not implemented")
 }
@@ -246,24 +218,6 @@ func _Cmd_PlayerFetchHistoryMsg_Handler(srv interface{}, ctx context.Context, de
 	return interceptor(ctx, in, info, handler)
 }
 
-func _Cmd_PlayerFetchMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(PlayerFetchMsgReq)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(CmdServer).PlayerFetchMsg(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pb.Cmd/playerFetchMsg",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(CmdServer).PlayerFetchMsg(ctx, req.(*PlayerFetchMsgReq))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
 func _Cmd_PlayerSendMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(PlayerSendMsgReq)
 	if err := dec(in); err != nil {
@@ -372,24 +326,6 @@ func _Cmd_CsFetchHistoryMsg_Handler(srv interface{}, ctx context.Context, dec fu
 	return interceptor(ctx, in, info, handler)
 }
 
-func _Cmd_CsFetchMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(CsFetchMsgReq)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(CmdServer).CsFetchMsg(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/pb.Cmd/csFetchMsg",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(CmdServer).CsFetchMsg(ctx, req.(*CsFetchMsgReq))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
 func _Cmd_CsSendMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(CsSendMsgReq)
 	if err := dec(in); err != nil {
@@ -423,10 +359,6 @@ var Cmd_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "playerFetchHistoryMsg",
 			Handler:    _Cmd_PlayerFetchHistoryMsg_Handler,
 		},
-		{
-			MethodName: "playerFetchMsg",
-			Handler:    _Cmd_PlayerFetchMsg_Handler,
-		},
 		{
 			MethodName: "playerSendMsg",
 			Handler:    _Cmd_PlayerSendMsg_Handler,
@@ -451,10 +383,6 @@ var Cmd_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "csFetchHistoryMsg",
 			Handler:    _Cmd_CsFetchHistoryMsg_Handler,
 		},
-		{
-			MethodName: "csFetchMsg",
-			Handler:    _Cmd_CsFetchMsg_Handler,
-		},
 		{
 			MethodName: "csSendMsg",
 			Handler:    _Cmd_CsSendMsg_Handler,

+ 21 - 0
core/inner/rpc/etc/inner.yaml

@@ -0,0 +1,21 @@
+Name: inner.rpc
+ListenOn: 127.0.0.1:10500
+
+Telemetry:
+  Name: cmd-rpc
+  Endpoint: http://localhost:14268/api/traces
+  Sampler: 1.0
+  Batcher: jaeger
+
+KqRecvMsgConf:
+  Brokers:
+    - localhost:9092
+  Topic: send-box-topic
+  GroupId: inner-rpc
+
+KqSendMsgConf:
+  Brokers:
+    - localhost:9092
+  Topic: recv-box-topic
+  GroupId:
+

+ 39 - 0
core/inner/rpc/inner.go

@@ -0,0 +1,39 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"ylink/core/inner/rpc/internal/config"
+	"ylink/core/inner/rpc/internal/server"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+
+	"github.com/zeromicro/go-zero/core/conf"
+	"github.com/zeromicro/go-zero/core/service"
+	"github.com/zeromicro/go-zero/zrpc"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/reflection"
+)
+
+var configFile = flag.String("f", "etc/inner.yaml", "the config file")
+
+func main() {
+	flag.Parse()
+
+	var c config.Config
+	conf.MustLoad(*configFile, &c)
+	ctx := svc.NewServiceContext(c)
+	svr := server.NewInnerServer(ctx)
+
+	s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
+		pb.RegisterInnerServer(grpcServer, svr)
+
+		if c.Mode == service.DevMode || c.Mode == service.TestMode {
+			reflection.Register(grpcServer)
+		}
+	})
+	defer s.Stop()
+
+	fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
+	s.Start()
+}

+ 61 - 0
core/inner/rpc/inner/inner.go

@@ -0,0 +1,61 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: inner.proto
+
+package inner
+
+import (
+	"context"
+
+	"ylink/core/inner/rpc/pb"
+
+	"github.com/zeromicro/go-zero/zrpc"
+	"google.golang.org/grpc"
+)
+
+type (
+	InnerCsConnectPlayerReq     = pb.InnerCsConnectPlayerReq
+	InnerCsConnectPlayerResp    = pb.InnerCsConnectPlayerResp
+	InnerCsFetchPlayerQueueReq  = pb.InnerCsFetchPlayerQueueReq
+	InnerCsFetchPlayerQueueResp = pb.InnerCsFetchPlayerQueueResp
+	InnerPlayerDisconnectReq    = pb.InnerPlayerDisconnectReq
+	InnerPlayerDisconnectResp   = pb.InnerPlayerDisconnectResp
+	InnerPlayerFetchCsInfoReq   = pb.InnerPlayerFetchCsInfoReq
+	InnerPlayerFetchCsInfoResp  = pb.InnerPlayerFetchCsInfoResp
+
+	Inner interface {
+		PlayerFetchCsInfo(ctx context.Context, in *InnerPlayerFetchCsInfoReq, opts ...grpc.CallOption) (*InnerPlayerFetchCsInfoResp, error)
+		PlayerDisconnect(ctx context.Context, in *InnerPlayerDisconnectReq, opts ...grpc.CallOption) (*InnerPlayerDisconnectResp, error)
+		CsFetchPlayerQueue(ctx context.Context, in *InnerCsFetchPlayerQueueReq, opts ...grpc.CallOption) (*InnerCsFetchPlayerQueueResp, error)
+		CsConnectPlayer(ctx context.Context, in *InnerCsConnectPlayerReq, opts ...grpc.CallOption) (*InnerCsConnectPlayerResp, error)
+	}
+
+	defaultInner struct {
+		cli zrpc.Client
+	}
+)
+
+func NewInner(cli zrpc.Client) Inner {
+	return &defaultInner{
+		cli: cli,
+	}
+}
+
+func (m *defaultInner) PlayerFetchCsInfo(ctx context.Context, in *InnerPlayerFetchCsInfoReq, opts ...grpc.CallOption) (*InnerPlayerFetchCsInfoResp, error) {
+	client := pb.NewInnerClient(m.cli.Conn())
+	return client.PlayerFetchCsInfo(ctx, in, opts...)
+}
+
+func (m *defaultInner) PlayerDisconnect(ctx context.Context, in *InnerPlayerDisconnectReq, opts ...grpc.CallOption) (*InnerPlayerDisconnectResp, error) {
+	client := pb.NewInnerClient(m.cli.Conn())
+	return client.PlayerDisconnect(ctx, in, opts...)
+}
+
+func (m *defaultInner) CsFetchPlayerQueue(ctx context.Context, in *InnerCsFetchPlayerQueueReq, opts ...grpc.CallOption) (*InnerCsFetchPlayerQueueResp, error) {
+	client := pb.NewInnerClient(m.cli.Conn())
+	return client.CsFetchPlayerQueue(ctx, in, opts...)
+}
+
+func (m *defaultInner) CsConnectPlayer(ctx context.Context, in *InnerCsConnectPlayerReq, opts ...grpc.CallOption) (*InnerCsConnectPlayerResp, error) {
+	client := pb.NewInnerClient(m.cli.Conn())
+	return client.CsConnectPlayer(ctx, in, opts...)
+}

+ 12 - 0
core/inner/rpc/internal/config/config.go

@@ -0,0 +1,12 @@
+package config
+
+import (
+	"github.com/zeromicro/go-zero/zrpc"
+	"ylink/ext/kafka"
+)
+
+type Config struct {
+	zrpc.RpcServerConf
+	KqRecvMsgConf kafka.KqConfig
+	KqSendMsgConf kafka.KqConfig
+}

+ 12 - 0
core/inner/rpc/internal/ext/global.go

@@ -0,0 +1,12 @@
+//@File     global.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package ext
+
+import "ylink/ext/ds/treemap"
+
+var (
+	IdMap *treemap.Map
+	CsMap *treemap.Map
+)

+ 71 - 0
core/inner/rpc/internal/ext/sendboxhandler.go

@@ -0,0 +1,71 @@
+//@File     sendboxhandler.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package ext
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/Shopify/sarama"
+	"github.com/zeromicro/go-zero/core/logx"
+	"ylink/ext/ds/treemap"
+	"ylink/ext/kafka"
+	"ylink/ext/model"
+)
+
+type callback func(msg []byte)
+
+type SendBoxConsumerHandler struct {
+	callbacks     map[string]callback
+	producer      *kafka.Producer
+	ConsumerGroup *kafka.ConsumerGroup
+}
+
+func (handler *SendBoxConsumerHandler) Init(c kafka.KqConfig, producer *kafka.Producer) {
+	handler.callbacks = make(map[string]callback)
+	handler.callbacks[c.Topic] = handler.handleMessage
+	handler.producer = producer
+	handler.ConsumerGroup = kafka.NewConsumerGroup(&kafka.ConsumerGroupConfig{
+		KafkaVersion:   sarama.V0_10_2_0,
+		OffsetsInitial: sarama.OffsetNewest,
+		IsReturnErr:    false,
+	}, c.Brokers, []string{c.Topic}, c.GroupId)
+}
+
+func (handler *SendBoxConsumerHandler) handleMessage(msg []byte) {
+	logx.WithContext(context.Background()).Infof("message recv from send-box, %s", string(msg))
+	// todo 将message转发到recv-box
+
+	var message model.ChatMessage
+	err := json.Unmarshal(msg, &message)
+	if err != nil {
+		logx.WithContext(context.Background()).Errorf("unmarshal message err: %s", err.Error())
+		return
+	}
+	if len(message.ReceiverId) == 0 {
+		// 玩家发的消息
+		p2cMap := IdMap.Get(message.GameId).(*treemap.Map)
+		message.ReceiverId = p2cMap.Get(message.SenderId).(string)
+		b, _ := json.Marshal(message)
+		handler.producer.SendMessage(string(b), message.ReceiverId)
+	} else {
+		handler.producer.SendMessage(string(msg), message.ReceiverId)
+	}
+}
+
+func (SendBoxConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error {
+	return nil
+}
+
+func (SendBoxConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error {
+	return nil
+}
+
+func (handler *SendBoxConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
+	for msg := range claim.Messages() {
+		logx.WithContext(context.Background()).Infof("send-box get info to db, topic: %s, partition: %d, msg: %s", msg.Topic, msg.Partition, string(msg.Value))
+		handler.callbacks[msg.Topic](msg.Value)
+	}
+	return nil
+}

+ 29 - 0
core/inner/rpc/internal/logic/csconnectplayerlogic.go

@@ -0,0 +1,29 @@
+package logic
+
+import (
+	"context"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CsConnectPlayerLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewCsConnectPlayerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CsConnectPlayerLogic {
+	return &CsConnectPlayerLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *CsConnectPlayerLogic) CsConnectPlayer(in *pb.InnerCsConnectPlayerReq) (*pb.InnerCsConnectPlayerResp, error) {
+	// todo: 建立玩家-客服的映射关系
+
+	return &pb.InnerCsConnectPlayerResp{}, nil
+}

+ 50 - 0
core/inner/rpc/internal/logic/csfetchplayerqueuelogic.go

@@ -0,0 +1,50 @@
+package logic
+
+import (
+	"context"
+	"github.com/pkg/errors"
+	"google.golang.org/protobuf/types/known/structpb"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+	"ylink/ext/result"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CsFetchPlayerQueueLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewCsFetchPlayerQueueLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CsFetchPlayerQueueLogic {
+	return &CsFetchPlayerQueueLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *CsFetchPlayerQueueLogic) CsFetchPlayerQueue(in *pb.InnerCsFetchPlayerQueueReq) (*pb.InnerCsFetchPlayerQueueResp, error) {
+	// todo: 查询等待用户的队列
+
+	list, err := structpb.NewList([]interface{}{
+		map[string]interface{}{
+			"player_id": "player1111",
+			"game_id":   "game1231",
+			"wait_time": 1000,
+		},
+		map[string]interface{}{
+			"player_id": "player2222",
+			"game_id":   "game1231",
+			"wait_time": 10,
+		},
+	})
+	if err != nil {
+		return nil, errors.Wrap(result.NewErrMsg("fetch player wait queue error"), "")
+	}
+
+	return &pb.InnerCsFetchPlayerQueueResp{
+		List: list,
+	}, nil
+}

+ 29 - 0
core/inner/rpc/internal/logic/playerdisconnectlogic.go

@@ -0,0 +1,29 @@
+package logic
+
+import (
+	"context"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type PlayerDisconnectLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewPlayerDisconnectLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PlayerDisconnectLogic {
+	return &PlayerDisconnectLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *PlayerDisconnectLogic) PlayerDisconnect(in *pb.InnerPlayerDisconnectReq) (*pb.InnerPlayerDisconnectResp, error) {
+	// todo: 修改玩家在线状态
+
+	return &pb.InnerPlayerDisconnectResp{}, nil
+}

+ 35 - 0
core/inner/rpc/internal/logic/playerfetchcsinfologic.go

@@ -0,0 +1,35 @@
+package logic
+
+import (
+	"context"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type PlayerFetchCsInfoLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewPlayerFetchCsInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PlayerFetchCsInfoLogic {
+	return &PlayerFetchCsInfoLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+func (l *PlayerFetchCsInfoLogic) PlayerFetchCsInfo(in *pb.InnerPlayerFetchCsInfoReq) (*pb.InnerPlayerFetchCsInfoResp, error) {
+	// todo: 修改玩家在线状态
+
+	return &pb.InnerPlayerFetchCsInfoResp{
+		CsId:         in.CsId,
+		CsNickname:   "vip客服1231",
+		CsAvatarUrl:  "https://www.baiduc.om",
+		CsSignature:  "服务时间:9:30-20:30",
+		OnlineStatus: 1,
+	}, nil
+}

+ 43 - 0
core/inner/rpc/internal/server/innerserver.go

@@ -0,0 +1,43 @@
+// Code generated by goctl. DO NOT EDIT!
+// Source: inner.proto
+
+package server
+
+import (
+	"context"
+
+	"ylink/core/inner/rpc/internal/logic"
+	"ylink/core/inner/rpc/internal/svc"
+	"ylink/core/inner/rpc/pb"
+)
+
+type InnerServer struct {
+	svcCtx *svc.ServiceContext
+	pb.UnimplementedInnerServer
+}
+
+func NewInnerServer(svcCtx *svc.ServiceContext) *InnerServer {
+	return &InnerServer{
+		svcCtx: svcCtx,
+	}
+}
+
+func (s *InnerServer) PlayerFetchCsInfo(ctx context.Context, in *pb.InnerPlayerFetchCsInfoReq) (*pb.InnerPlayerFetchCsInfoResp, error) {
+	l := logic.NewPlayerFetchCsInfoLogic(ctx, s.svcCtx)
+	return l.PlayerFetchCsInfo(in)
+}
+
+func (s *InnerServer) PlayerDisconnect(ctx context.Context, in *pb.InnerPlayerDisconnectReq) (*pb.InnerPlayerDisconnectResp, error) {
+	l := logic.NewPlayerDisconnectLogic(ctx, s.svcCtx)
+	return l.PlayerDisconnect(in)
+}
+
+func (s *InnerServer) CsFetchPlayerQueue(ctx context.Context, in *pb.InnerCsFetchPlayerQueueReq) (*pb.InnerCsFetchPlayerQueueResp, error) {
+	l := logic.NewCsFetchPlayerQueueLogic(ctx, s.svcCtx)
+	return l.CsFetchPlayerQueue(in)
+}
+
+func (s *InnerServer) CsConnectPlayer(ctx context.Context, in *pb.InnerCsConnectPlayerReq) (*pb.InnerCsConnectPlayerResp, error) {
+	l := logic.NewCsConnectPlayerLogic(ctx, s.svcCtx)
+	return l.CsConnectPlayer(in)
+}

+ 67 - 0
core/inner/rpc/internal/svc/servicecontext.go

@@ -0,0 +1,67 @@
+package svc
+
+import (
+	"ylink/core/inner/rpc/internal/config"
+	"ylink/core/inner/rpc/internal/ext"
+	"ylink/ext/ds/treemap"
+	"ylink/ext/kafka"
+	"ylink/ext/model"
+)
+
+type ServiceContext struct {
+	Config          config.Config
+	RecvBoxProducer *kafka.Producer
+}
+
+func NewServiceContext(c config.Config) *ServiceContext {
+	fetchCsCenterInfo()
+	recvBoxProducer := kafka.NewKafkaProducer(c.KqSendMsgConf.Brokers, c.KqSendMsgConf.Topic)
+	var sendBoxHandler ext.SendBoxConsumerHandler
+	sendBoxHandler.Init(c.KqRecvMsgConf, recvBoxProducer)
+	go sendBoxHandler.ConsumerGroup.RegisterHandleAndConsumer(&sendBoxHandler)
+	return &ServiceContext{
+		Config: c,
+	}
+}
+
+func fetchCsCenterInfo() {
+	// mock info
+	mockInfo()
+}
+
+func mockInfo() {
+	ext.IdMap = treemap.New(treemap.WithGoroutineSafe())
+	ext.CsMap = treemap.New(treemap.WithGoroutineSafe())
+
+	game1231P2cMap := treemap.New(treemap.WithGoroutineSafe())
+	game1231P2cMap.Insert("player1231", "cs_1231")
+	game1231P2cMap.Insert("player1111", "cs_2222")
+
+	game1111P2cMap := treemap.New(treemap.WithGoroutineSafe())
+	game1111P2cMap.Insert("player1231", "cs_1111")
+
+	ext.IdMap.Insert("game1231", game1231P2cMap)
+	ext.IdMap.Insert("game1111", game1111P2cMap)
+
+	ext.CsMap.Insert("cs_1231", &model.CsInfo{
+		CsId:         "cs_1231",
+		CsNickname:   "客服1231",
+		CsAvatarUrl:  "https://www.baidu.com",
+		CsSignature:  "我是客服1231",
+		OnlineStatus: 1,
+	})
+	ext.CsMap.Insert("cs_1111", &model.CsInfo{
+		CsId:         "cs_1111",
+		CsNickname:   "客服1111",
+		CsAvatarUrl:  "https://www.baidu.com",
+		CsSignature:  "我是客服1111",
+		OnlineStatus: 1,
+	})
+	ext.CsMap.Insert("cs_2222", &model.CsInfo{
+		CsId:         "cs_2222",
+		CsNickname:   "客服2222",
+		CsAvatarUrl:  "https://www.baidu.com",
+		CsSignature:  "我是客服2222",
+		OnlineStatus: 0,
+	})
+}

+ 702 - 0
core/inner/rpc/pb/inner.pb.go

@@ -0,0 +1,702 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.0
+// 	protoc        v3.19.4
+// source: pb/inner.proto
+
+package pb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	structpb "google.golang.org/protobuf/types/known/structpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+//*
+//Player Command Request Bean
+type InnerPlayerFetchCsInfoReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlayerId string `protobuf:"bytes,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"`
+	GameId   string `protobuf:"bytes,2,opt,name=game_id,json=gameId,proto3" json:"game_id,omitempty"`
+	CsId     string `protobuf:"bytes,3,opt,name=cs_id,json=csId,proto3" json:"cs_id,omitempty"`
+}
+
+func (x *InnerPlayerFetchCsInfoReq) Reset() {
+	*x = InnerPlayerFetchCsInfoReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerPlayerFetchCsInfoReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerPlayerFetchCsInfoReq) ProtoMessage() {}
+
+func (x *InnerPlayerFetchCsInfoReq) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerPlayerFetchCsInfoReq.ProtoReflect.Descriptor instead.
+func (*InnerPlayerFetchCsInfoReq) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *InnerPlayerFetchCsInfoReq) GetPlayerId() string {
+	if x != nil {
+		return x.PlayerId
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoReq) GetGameId() string {
+	if x != nil {
+		return x.GameId
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoReq) GetCsId() string {
+	if x != nil {
+		return x.CsId
+	}
+	return ""
+}
+
+type InnerPlayerFetchCsInfoResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	CsId         string `protobuf:"bytes,1,opt,name=cs_id,json=csId,proto3" json:"cs_id,omitempty"`
+	CsNickname   string `protobuf:"bytes,2,opt,name=cs_nickname,json=csNickname,proto3" json:"cs_nickname,omitempty"`
+	CsAvatarUrl  string `protobuf:"bytes,3,opt,name=cs_avatar_url,json=csAvatarUrl,proto3" json:"cs_avatar_url,omitempty"`
+	CsSignature  string `protobuf:"bytes,4,opt,name=cs_signature,json=csSignature,proto3" json:"cs_signature,omitempty"`
+	OnlineStatus int64  `protobuf:"varint,5,opt,name=online_status,json=onlineStatus,proto3" json:"online_status,omitempty"`
+}
+
+func (x *InnerPlayerFetchCsInfoResp) Reset() {
+	*x = InnerPlayerFetchCsInfoResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerPlayerFetchCsInfoResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerPlayerFetchCsInfoResp) ProtoMessage() {}
+
+func (x *InnerPlayerFetchCsInfoResp) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerPlayerFetchCsInfoResp.ProtoReflect.Descriptor instead.
+func (*InnerPlayerFetchCsInfoResp) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *InnerPlayerFetchCsInfoResp) GetCsId() string {
+	if x != nil {
+		return x.CsId
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoResp) GetCsNickname() string {
+	if x != nil {
+		return x.CsNickname
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoResp) GetCsAvatarUrl() string {
+	if x != nil {
+		return x.CsAvatarUrl
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoResp) GetCsSignature() string {
+	if x != nil {
+		return x.CsSignature
+	}
+	return ""
+}
+
+func (x *InnerPlayerFetchCsInfoResp) GetOnlineStatus() int64 {
+	if x != nil {
+		return x.OnlineStatus
+	}
+	return 0
+}
+
+type InnerPlayerDisconnectReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlayerId string `protobuf:"bytes,1,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"`
+	GameId   string `protobuf:"bytes,2,opt,name=game_id,json=gameId,proto3" json:"game_id,omitempty"`
+}
+
+func (x *InnerPlayerDisconnectReq) Reset() {
+	*x = InnerPlayerDisconnectReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerPlayerDisconnectReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerPlayerDisconnectReq) ProtoMessage() {}
+
+func (x *InnerPlayerDisconnectReq) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerPlayerDisconnectReq.ProtoReflect.Descriptor instead.
+func (*InnerPlayerDisconnectReq) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *InnerPlayerDisconnectReq) GetPlayerId() string {
+	if x != nil {
+		return x.PlayerId
+	}
+	return ""
+}
+
+func (x *InnerPlayerDisconnectReq) GetGameId() string {
+	if x != nil {
+		return x.GameId
+	}
+	return ""
+}
+
+type InnerPlayerDisconnectResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *InnerPlayerDisconnectResp) Reset() {
+	*x = InnerPlayerDisconnectResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerPlayerDisconnectResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerPlayerDisconnectResp) ProtoMessage() {}
+
+func (x *InnerPlayerDisconnectResp) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerPlayerDisconnectResp.ProtoReflect.Descriptor instead.
+func (*InnerPlayerDisconnectResp) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{3}
+}
+
+//*
+//Cs Command Request Bean
+type InnerCsFetchPlayerQueueReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Limit int64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"`
+}
+
+func (x *InnerCsFetchPlayerQueueReq) Reset() {
+	*x = InnerCsFetchPlayerQueueReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerCsFetchPlayerQueueReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerCsFetchPlayerQueueReq) ProtoMessage() {}
+
+func (x *InnerCsFetchPlayerQueueReq) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerCsFetchPlayerQueueReq.ProtoReflect.Descriptor instead.
+func (*InnerCsFetchPlayerQueueReq) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *InnerCsFetchPlayerQueueReq) GetLimit() int64 {
+	if x != nil {
+		return x.Limit
+	}
+	return 0
+}
+
+type InnerCsFetchPlayerQueueResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Total int64               `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
+	List  *structpb.ListValue `protobuf:"bytes,2,opt,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *InnerCsFetchPlayerQueueResp) Reset() {
+	*x = InnerCsFetchPlayerQueueResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerCsFetchPlayerQueueResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerCsFetchPlayerQueueResp) ProtoMessage() {}
+
+func (x *InnerCsFetchPlayerQueueResp) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerCsFetchPlayerQueueResp.ProtoReflect.Descriptor instead.
+func (*InnerCsFetchPlayerQueueResp) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *InnerCsFetchPlayerQueueResp) GetTotal() int64 {
+	if x != nil {
+		return x.Total
+	}
+	return 0
+}
+
+func (x *InnerCsFetchPlayerQueueResp) GetList() *structpb.ListValue {
+	if x != nil {
+		return x.List
+	}
+	return nil
+}
+
+type InnerCsConnectPlayerReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	CsId     string `protobuf:"bytes,1,opt,name=cs_id,json=csId,proto3" json:"cs_id,omitempty"`
+	PlayerId string `protobuf:"bytes,2,opt,name=player_id,json=playerId,proto3" json:"player_id,omitempty"`
+	GameId   string `protobuf:"bytes,3,opt,name=game_id,json=gameId,proto3" json:"game_id,omitempty"`
+}
+
+func (x *InnerCsConnectPlayerReq) Reset() {
+	*x = InnerCsConnectPlayerReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerCsConnectPlayerReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerCsConnectPlayerReq) ProtoMessage() {}
+
+func (x *InnerCsConnectPlayerReq) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerCsConnectPlayerReq.ProtoReflect.Descriptor instead.
+func (*InnerCsConnectPlayerReq) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *InnerCsConnectPlayerReq) GetCsId() string {
+	if x != nil {
+		return x.CsId
+	}
+	return ""
+}
+
+func (x *InnerCsConnectPlayerReq) GetPlayerId() string {
+	if x != nil {
+		return x.PlayerId
+	}
+	return ""
+}
+
+func (x *InnerCsConnectPlayerReq) GetGameId() string {
+	if x != nil {
+		return x.GameId
+	}
+	return ""
+}
+
+type InnerCsConnectPlayerResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *InnerCsConnectPlayerResp) Reset() {
+	*x = InnerCsConnectPlayerResp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_pb_inner_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InnerCsConnectPlayerResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InnerCsConnectPlayerResp) ProtoMessage() {}
+
+func (x *InnerCsConnectPlayerResp) ProtoReflect() protoreflect.Message {
+	mi := &file_pb_inner_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InnerCsConnectPlayerResp.ProtoReflect.Descriptor instead.
+func (*InnerCsConnectPlayerResp) Descriptor() ([]byte, []int) {
+	return file_pb_inner_proto_rawDescGZIP(), []int{7}
+}
+
+var File_pb_inner_proto protoreflect.FileDescriptor
+
+var file_pb_inner_proto_rawDesc = []byte{
+	0x0a, 0x0e, 0x70, 0x62, 0x2f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x12, 0x02, 0x70, 0x62, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x22, 0x66, 0x0a, 0x19, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x12,
+	0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07,
+	0x67, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67,
+	0x61, 0x6d, 0x65, 0x49, 0x64, 0x12, 0x13, 0x0a, 0x05, 0x63, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x73, 0x49, 0x64, 0x22, 0xbe, 0x01, 0x0a, 0x1a, 0x49,
+	0x6e, 0x6e, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43,
+	0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x12, 0x13, 0x0a, 0x05, 0x63, 0x73, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x73, 0x49, 0x64, 0x12, 0x1f,
+	0x0a, 0x0b, 0x63, 0x73, 0x5f, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x73, 0x4e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x22, 0x0a, 0x0d, 0x63, 0x73, 0x5f, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x73, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72,
+	0x55, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
+	0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x73, 0x53, 0x69, 0x67,
+	0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
+	0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6f,
+	0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x50, 0x0a, 0x18, 0x49,
+	0x6e, 0x6e, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e,
+	0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x22, 0x1b, 0x0a,
+	0x19, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63,
+	0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x22, 0x32, 0x0a, 0x1a, 0x49, 0x6e,
+	0x6e, 0x65, 0x72, 0x43, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72,
+	0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69,
+	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x63,
+	0x0a, 0x1b, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14, 0x0a,
+	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x04, 0x6c,
+	0x69, 0x73, 0x74, 0x22, 0x64, 0x0a, 0x17, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x43, 0x6f,
+	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x13,
+	0x0a, 0x05, 0x63, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63,
+	0x73, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x69, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x64,
+	0x12, 0x17, 0x0a, 0x07, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x06, 0x67, 0x61, 0x6d, 0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x49, 0x6e, 0x6e,
+	0x65, 0x72, 0x43, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x52, 0x65, 0x73, 0x70, 0x32, 0xd1, 0x02, 0x0a, 0x05, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x12,
+	0x52, 0x0a, 0x11, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x73,
+	0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x50,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x73, 0x49, 0x6e, 0x66, 0x6f,
+	0x52, 0x65, 0x71, 0x1a, 0x1e, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x50, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x46, 0x65, 0x74, 0x63, 0x68, 0x43, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+	0x65, 0x73, 0x70, 0x12, 0x4f, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x69, 0x73,
+	0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x6e,
+	0x65, 0x72, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
+	0x63, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72,
+	0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+	0x52, 0x65, 0x73, 0x70, 0x12, 0x55, 0x0a, 0x12, 0x63, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x62, 0x2e,
+	0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x70, 0x62, 0x2e,
+	0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x46, 0x65, 0x74, 0x63, 0x68, 0x50, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x4c, 0x0a, 0x0f, 0x63,
+	0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1b,
+	0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
+	0x63, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x70, 0x62,
+	0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70,
+	0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_pb_inner_proto_rawDescOnce sync.Once
+	file_pb_inner_proto_rawDescData = file_pb_inner_proto_rawDesc
+)
+
+func file_pb_inner_proto_rawDescGZIP() []byte {
+	file_pb_inner_proto_rawDescOnce.Do(func() {
+		file_pb_inner_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_inner_proto_rawDescData)
+	})
+	return file_pb_inner_proto_rawDescData
+}
+
+var file_pb_inner_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_pb_inner_proto_goTypes = []interface{}{
+	(*InnerPlayerFetchCsInfoReq)(nil),   // 0: pb.InnerPlayerFetchCsInfoReq
+	(*InnerPlayerFetchCsInfoResp)(nil),  // 1: pb.InnerPlayerFetchCsInfoResp
+	(*InnerPlayerDisconnectReq)(nil),    // 2: pb.InnerPlayerDisconnectReq
+	(*InnerPlayerDisconnectResp)(nil),   // 3: pb.InnerPlayerDisconnectResp
+	(*InnerCsFetchPlayerQueueReq)(nil),  // 4: pb.InnerCsFetchPlayerQueueReq
+	(*InnerCsFetchPlayerQueueResp)(nil), // 5: pb.InnerCsFetchPlayerQueueResp
+	(*InnerCsConnectPlayerReq)(nil),     // 6: pb.InnerCsConnectPlayerReq
+	(*InnerCsConnectPlayerResp)(nil),    // 7: pb.InnerCsConnectPlayerResp
+	(*structpb.ListValue)(nil),          // 8: google.protobuf.ListValue
+}
+var file_pb_inner_proto_depIdxs = []int32{
+	8, // 0: pb.InnerCsFetchPlayerQueueResp.list:type_name -> google.protobuf.ListValue
+	0, // 1: pb.Inner.playerFetchCsInfo:input_type -> pb.InnerPlayerFetchCsInfoReq
+	2, // 2: pb.Inner.playerDisconnect:input_type -> pb.InnerPlayerDisconnectReq
+	4, // 3: pb.Inner.csFetchPlayerQueue:input_type -> pb.InnerCsFetchPlayerQueueReq
+	6, // 4: pb.Inner.csConnectPlayer:input_type -> pb.InnerCsConnectPlayerReq
+	1, // 5: pb.Inner.playerFetchCsInfo:output_type -> pb.InnerPlayerFetchCsInfoResp
+	3, // 6: pb.Inner.playerDisconnect:output_type -> pb.InnerPlayerDisconnectResp
+	5, // 7: pb.Inner.csFetchPlayerQueue:output_type -> pb.InnerCsFetchPlayerQueueResp
+	7, // 8: pb.Inner.csConnectPlayer:output_type -> pb.InnerCsConnectPlayerResp
+	5, // [5:9] is the sub-list for method output_type
+	1, // [1:5] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_pb_inner_proto_init() }
+func file_pb_inner_proto_init() {
+	if File_pb_inner_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_pb_inner_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerPlayerFetchCsInfoReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerPlayerFetchCsInfoResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerPlayerDisconnectReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerPlayerDisconnectResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerCsFetchPlayerQueueReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerCsFetchPlayerQueueResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerCsConnectPlayerReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_pb_inner_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InnerCsConnectPlayerResp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_pb_inner_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   8,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_pb_inner_proto_goTypes,
+		DependencyIndexes: file_pb_inner_proto_depIdxs,
+		MessageInfos:      file_pb_inner_proto_msgTypes,
+	}.Build()
+	File_pb_inner_proto = out.File
+	file_pb_inner_proto_rawDesc = nil
+	file_pb_inner_proto_goTypes = nil
+	file_pb_inner_proto_depIdxs = nil
+}

+ 59 - 0
core/inner/rpc/pb/inner.proto

@@ -0,0 +1,59 @@
+syntax = "proto3";
+
+option go_package = "./pb";
+
+package pb;
+
+import "google/protobuf/struct.proto";
+
+/**
+Player Command Request Bean
+ */
+message InnerPlayerFetchCsInfoReq{
+  string player_id = 1;
+  string game_id = 2;
+  string cs_id = 3;
+}
+
+message InnerPlayerFetchCsInfoResp{
+  string cs_id = 1;
+  string cs_nickname = 2;
+  string cs_avatar_url = 3;
+  string cs_signature = 4;
+  int64 online_status = 5;
+}
+
+message InnerPlayerDisconnectReq{
+  string player_id = 1;
+  string game_id = 2;
+}
+
+message InnerPlayerDisconnectResp{}
+
+/**
+Cs Command Request Bean
+ */
+message InnerCsFetchPlayerQueueReq {
+  int64 limit = 1;
+}
+
+message InnerCsFetchPlayerQueueResp{
+  int64 total = 1;
+  google.protobuf.ListValue list = 2;
+}
+
+message InnerCsConnectPlayerReq{
+  string cs_id = 1;
+  string player_id = 2;
+  string game_id = 3;
+}
+
+message InnerCsConnectPlayerResp{}
+
+service Inner {
+  rpc playerFetchCsInfo (InnerPlayerFetchCsInfoReq) returns (InnerPlayerFetchCsInfoResp);
+  rpc playerDisconnect (InnerPlayerDisconnectReq) returns (InnerPlayerDisconnectResp);
+
+  rpc csFetchPlayerQueue (InnerCsFetchPlayerQueueReq) returns (InnerCsFetchPlayerQueueResp);
+  rpc csConnectPlayer (InnerCsConnectPlayerReq) returns (InnerCsConnectPlayerResp);
+}

+ 213 - 0
core/inner/rpc/pb/inner_grpc.pb.go

@@ -0,0 +1,213 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: pb/inner.proto
+
+package pb
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+// InnerClient is the client API for Inner service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type InnerClient interface {
+	PlayerFetchCsInfo(ctx context.Context, in *InnerPlayerFetchCsInfoReq, opts ...grpc.CallOption) (*InnerPlayerFetchCsInfoResp, error)
+	PlayerDisconnect(ctx context.Context, in *InnerPlayerDisconnectReq, opts ...grpc.CallOption) (*InnerPlayerDisconnectResp, error)
+	CsFetchPlayerQueue(ctx context.Context, in *InnerCsFetchPlayerQueueReq, opts ...grpc.CallOption) (*InnerCsFetchPlayerQueueResp, error)
+	CsConnectPlayer(ctx context.Context, in *InnerCsConnectPlayerReq, opts ...grpc.CallOption) (*InnerCsConnectPlayerResp, error)
+}
+
+type innerClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewInnerClient(cc grpc.ClientConnInterface) InnerClient {
+	return &innerClient{cc}
+}
+
+func (c *innerClient) PlayerFetchCsInfo(ctx context.Context, in *InnerPlayerFetchCsInfoReq, opts ...grpc.CallOption) (*InnerPlayerFetchCsInfoResp, error) {
+	out := new(InnerPlayerFetchCsInfoResp)
+	err := c.cc.Invoke(ctx, "/pb.Inner/playerFetchCsInfo", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *innerClient) PlayerDisconnect(ctx context.Context, in *InnerPlayerDisconnectReq, opts ...grpc.CallOption) (*InnerPlayerDisconnectResp, error) {
+	out := new(InnerPlayerDisconnectResp)
+	err := c.cc.Invoke(ctx, "/pb.Inner/playerDisconnect", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *innerClient) CsFetchPlayerQueue(ctx context.Context, in *InnerCsFetchPlayerQueueReq, opts ...grpc.CallOption) (*InnerCsFetchPlayerQueueResp, error) {
+	out := new(InnerCsFetchPlayerQueueResp)
+	err := c.cc.Invoke(ctx, "/pb.Inner/csFetchPlayerQueue", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *innerClient) CsConnectPlayer(ctx context.Context, in *InnerCsConnectPlayerReq, opts ...grpc.CallOption) (*InnerCsConnectPlayerResp, error) {
+	out := new(InnerCsConnectPlayerResp)
+	err := c.cc.Invoke(ctx, "/pb.Inner/csConnectPlayer", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// InnerServer is the server API for Inner service.
+// All implementations must embed UnimplementedInnerServer
+// for forward compatibility
+type InnerServer interface {
+	PlayerFetchCsInfo(context.Context, *InnerPlayerFetchCsInfoReq) (*InnerPlayerFetchCsInfoResp, error)
+	PlayerDisconnect(context.Context, *InnerPlayerDisconnectReq) (*InnerPlayerDisconnectResp, error)
+	CsFetchPlayerQueue(context.Context, *InnerCsFetchPlayerQueueReq) (*InnerCsFetchPlayerQueueResp, error)
+	CsConnectPlayer(context.Context, *InnerCsConnectPlayerReq) (*InnerCsConnectPlayerResp, error)
+	mustEmbedUnimplementedInnerServer()
+}
+
+// UnimplementedInnerServer must be embedded to have forward compatible implementations.
+type UnimplementedInnerServer struct {
+}
+
+func (UnimplementedInnerServer) PlayerFetchCsInfo(context.Context, *InnerPlayerFetchCsInfoReq) (*InnerPlayerFetchCsInfoResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PlayerFetchCsInfo not implemented")
+}
+func (UnimplementedInnerServer) PlayerDisconnect(context.Context, *InnerPlayerDisconnectReq) (*InnerPlayerDisconnectResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method PlayerDisconnect not implemented")
+}
+func (UnimplementedInnerServer) CsFetchPlayerQueue(context.Context, *InnerCsFetchPlayerQueueReq) (*InnerCsFetchPlayerQueueResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CsFetchPlayerQueue not implemented")
+}
+func (UnimplementedInnerServer) CsConnectPlayer(context.Context, *InnerCsConnectPlayerReq) (*InnerCsConnectPlayerResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CsConnectPlayer not implemented")
+}
+func (UnimplementedInnerServer) mustEmbedUnimplementedInnerServer() {}
+
+// UnsafeInnerServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to InnerServer will
+// result in compilation errors.
+type UnsafeInnerServer interface {
+	mustEmbedUnimplementedInnerServer()
+}
+
+func RegisterInnerServer(s grpc.ServiceRegistrar, srv InnerServer) {
+	s.RegisterService(&Inner_ServiceDesc, srv)
+}
+
+func _Inner_PlayerFetchCsInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InnerPlayerFetchCsInfoReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(InnerServer).PlayerFetchCsInfo(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pb.Inner/playerFetchCsInfo",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(InnerServer).PlayerFetchCsInfo(ctx, req.(*InnerPlayerFetchCsInfoReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Inner_PlayerDisconnect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InnerPlayerDisconnectReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(InnerServer).PlayerDisconnect(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pb.Inner/playerDisconnect",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(InnerServer).PlayerDisconnect(ctx, req.(*InnerPlayerDisconnectReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Inner_CsFetchPlayerQueue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InnerCsFetchPlayerQueueReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(InnerServer).CsFetchPlayerQueue(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pb.Inner/csFetchPlayerQueue",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(InnerServer).CsFetchPlayerQueue(ctx, req.(*InnerCsFetchPlayerQueueReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Inner_CsConnectPlayer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InnerCsConnectPlayerReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(InnerServer).CsConnectPlayer(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/pb.Inner/csConnectPlayer",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(InnerServer).CsConnectPlayer(ctx, req.(*InnerCsConnectPlayerReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// Inner_ServiceDesc is the grpc.ServiceDesc for Inner service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Inner_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "pb.Inner",
+	HandlerType: (*InnerServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "playerFetchCsInfo",
+			Handler:    _Inner_PlayerFetchCsInfo_Handler,
+		},
+		{
+			MethodName: "playerDisconnect",
+			Handler:    _Inner_PlayerDisconnect_Handler,
+		},
+		{
+			MethodName: "csFetchPlayerQueue",
+			Handler:    _Inner_CsFetchPlayerQueue_Handler,
+		},
+		{
+			MethodName: "csConnectPlayer",
+			Handler:    _Inner_CsConnectPlayer_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "pb/inner.proto",
+}

+ 1 - 1
docker-compose-env.yml

@@ -115,7 +115,7 @@ services:
     ports:
       - "9092:9092"
     environment:
-      - "KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092"
+      - "KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092"
       - "KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 "
       - "KAFKA_ADVERTISED_HOST_NAME=kafka"
       - "KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181"

+ 73 - 0
ext/ds/rbtree/iterator.go

@@ -0,0 +1,73 @@
+//@File     iterator.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package rbtree
+
+import "ylink/ext/utils/iterator"
+
+type RbTreeIterator struct {
+	node *Node
+}
+
+// NewIterator creates a RbTreeIterator from the passed node
+func NewIterator(node *Node) *RbTreeIterator {
+	return &RbTreeIterator{node: node}
+}
+
+// IsValid returns true if the iterator is valid, otherwise returns false
+func (iter *RbTreeIterator) IsValid() bool {
+	if iter.node != nil {
+		return true
+	}
+	return false
+}
+
+// Next moves the pointer of the iterator to the next node, and returns itself
+func (iter *RbTreeIterator) Next() iterator.ConstIterator {
+	if iter.IsValid() {
+		iter.node = iter.node.Next()
+	}
+	return iter
+}
+
+// Prev moves the pointer of the iterator to the previous node, and returns itself
+func (iter *RbTreeIterator) Prev() iterator.ConstBidIterator {
+	if iter.IsValid() {
+		iter.node = iter.node.Prev()
+	}
+	return iter
+}
+
+// Key returns the node's key of the iterator point to
+func (iter *RbTreeIterator) Key() interface{} {
+	return iter.node.Key()
+}
+
+// Value returns the node's value of the iterator point to
+func (iter *RbTreeIterator) Value() interface{} {
+	return iter.node.Value()
+}
+
+//SetValue sets the node's value of the iterator point to
+func (iter *RbTreeIterator) SetValue(val interface{}) error {
+	iter.node.SetValue(val)
+	return nil
+}
+
+// Clone clones the iterator into a new RbTreeIterator
+func (iter *RbTreeIterator) Clone() iterator.ConstIterator {
+	return NewIterator(iter.node)
+}
+
+// Equal returns true if the iterator is equal to the passed iterator
+func (iter *RbTreeIterator) Equal(other iterator.ConstIterator) bool {
+	otherIter, ok := other.(*RbTreeIterator)
+	if !ok {
+		return false
+	}
+	if otherIter.node == iter.node {
+		return true
+	}
+	return false
+}

+ 87 - 0
ext/ds/rbtree/node.go

@@ -0,0 +1,87 @@
+//@File     node.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package rbtree
+
+type Color bool
+
+const (
+	RED   = false
+	BLACK = true
+)
+
+type Node struct {
+	parent *Node
+	left   *Node
+	right  *Node
+	color  Color
+	key    interface{}
+	value  interface{}
+}
+
+func (node *Node) Key() interface{} {
+	return node.key
+}
+
+func (node *Node) Value() interface{} {
+	return node.value
+}
+
+func (node *Node) SetValue(value interface{}) {
+	node.value = value
+}
+
+func (node *Node) Next() *Node {
+	return successor(node)
+}
+
+func (node *Node) Prev() *Node {
+	return preSuccessor(node)
+}
+
+// successor returns the successor of the Node
+func successor(node *Node) *Node {
+	if node.right != nil {
+		return minimum(node.right)
+	}
+	y := node.parent
+	for y != nil && node == y.right {
+		node = y
+		y = node.parent
+	}
+	return y
+}
+
+// preSuccessor returns the preSuccessor of the Node
+func preSuccessor(node *Node) *Node {
+	if node.left != nil {
+		return maximum(node.left)
+	}
+	if node.parent != nil {
+		if node.parent.right == node {
+			return node.parent
+		}
+		for node.parent != nil && node.parent.left == node {
+			node = node.parent
+		}
+		return node.parent
+	}
+	return nil
+}
+
+// minimum finds the minimum Node of subtree n.
+func minimum(node *Node) *Node {
+	for node.left != nil {
+		node = node.left
+	}
+	return node
+}
+
+// maximum finds the maximum Node of subtree n.
+func maximum(node *Node) *Node {
+	for node.right != nil {
+		node = node.right
+	}
+	return node
+}

+ 481 - 0
ext/ds/rbtree/rbtree.go

@@ -0,0 +1,481 @@
+//@File     rbtree.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package rbtree
+
+import (
+	"fmt"
+	"ylink/ext/utils/comparator"
+	"ylink/ext/utils/visitor"
+)
+
+var defaultKeyComparator = comparator.BuiltinTypeComparator
+
+type Options struct {
+	keyCmp comparator.Comparator
+}
+
+// Option is a function type used to set Options
+type Option func(option *Options)
+
+//WithKeyComparator is used to set RbTree's key comparator
+func WithKeyComparator(cmp comparator.Comparator) Option {
+	return func(option *Options) {
+		option.keyCmp = cmp
+	}
+}
+
+type RbTree struct {
+	root   *Node
+	size   int
+	keyCmp comparator.Comparator
+}
+
+// New creates a new RbTree
+func New(opts ...Option) *RbTree {
+	option := Options{
+		keyCmp: defaultKeyComparator,
+	}
+	for _, opt := range opts {
+		opt(&option)
+	}
+	return &RbTree{keyCmp: option.keyCmp}
+}
+
+// Clear clears the RbTree
+func (tree *RbTree) Clear() {
+	tree.root = nil
+	tree.size = 0
+}
+
+// Find finds the first node that the key is equal to the passed key, and returns its value
+func (tree *RbTree) Find(key interface{}) interface{} {
+	n := tree.findFirstNode(key)
+	if n != nil {
+		return n.value
+	}
+	return nil
+}
+
+// FindNode the first node that the key is equal to the passed key and return it
+func (tree *RbTree) FindNode(key interface{}) *Node {
+	return tree.findFirstNode(key)
+}
+
+// Begin returns the node with minimum key in the RbTree
+func (tree *RbTree) Begin() *Node {
+	return tree.First()
+}
+
+// First returns the node with minimum key in the RbTree
+func (tree *RbTree) First() *Node {
+	if tree.root == nil {
+		return nil
+	}
+	return minimum(tree.root)
+}
+
+// RBegin returns the Node with maximum key in the RbTree
+func (tree *RbTree) RBegin() *Node {
+	return tree.Last()
+}
+
+// Last returns the Node with maximum key in the RbTree
+func (tree *RbTree) Last() *Node {
+	if tree.root == nil {
+		return nil
+	}
+	return maximum(tree.root)
+}
+
+// IterFirst returns the iterator of first node
+func (tree *RbTree) IterFirst() *RbTreeIterator {
+	return NewIterator(tree.First())
+}
+
+// IterLast returns the iterator of first node
+func (tree *RbTree) IterLast() *RbTreeIterator {
+	return NewIterator(tree.Last())
+}
+
+// Empty returns true if Tree is empty,otherwise returns false.
+func (tree *RbTree) Empty() bool {
+	if tree.size == 0 {
+		return true
+	}
+	return false
+}
+
+// Size returns the size of the rbtree.
+func (tree *RbTree) Size() int {
+	return tree.size
+}
+
+// Insert inserts a key-value pair into the RbTree.
+func (tree *RbTree) Insert(key, value interface{}) {
+	x := tree.root
+	var y *Node
+
+	for x != nil {
+		y = x
+		if tree.keyCmp(key, x.key) < 0 {
+			x = x.left
+		} else {
+			x = x.right
+		}
+	}
+
+	z := &Node{parent: y, color: RED, key: key, value: value}
+	tree.size++
+
+	if y == nil {
+		z.color = BLACK
+		tree.root = z
+		return
+	} else if tree.keyCmp(z.key, y.key) < 0 {
+		y.left = z
+	} else {
+		y.right = z
+	}
+	tree.rbInsertFixup(z)
+}
+
+func (tree *RbTree) rbInsertFixup(z *Node) {
+	var y *Node
+	for z.parent != nil && z.parent.color == RED {
+		if z.parent == z.parent.parent.left {
+			y = z.parent.parent.right
+			if y != nil && y.color == RED {
+				z.parent.color = BLACK
+				y.color = BLACK
+				z.parent.parent.color = RED
+				z = z.parent.parent
+			} else {
+				if z == z.parent.right {
+					z = z.parent
+					tree.leftRotate(z)
+				}
+				z.parent.color = BLACK
+				z.parent.parent.color = RED
+				tree.rightRotate(z.parent.parent)
+			}
+		} else {
+			y = z.parent.parent.left
+			if y != nil && y.color == RED {
+				z.parent.color = BLACK
+				y.color = BLACK
+				z.parent.parent.color = RED
+				z = z.parent.parent
+			} else {
+				if z == z.parent.left {
+					z = z.parent
+					tree.rightRotate(z)
+				}
+				z.parent.color = BLACK
+				z.parent.parent.color = RED
+				tree.leftRotate(z.parent.parent)
+			}
+		}
+	}
+	tree.root.color = BLACK
+}
+
+// Delete deletes node from the RbTree
+func (tree *RbTree) Delete(node *Node) {
+	z := node
+	if z == nil {
+		return
+	}
+
+	var x, y *Node
+	if z.left != nil && z.right != nil {
+		y = successor(z)
+	} else {
+		y = z
+	}
+
+	if y.left != nil {
+		x = y.left
+	} else {
+		x = y.right
+	}
+
+	xparent := y.parent
+	if x != nil {
+		x.parent = xparent
+	}
+	if y.parent == nil {
+		tree.root = x
+	} else if y == y.parent.left {
+		y.parent.left = x
+	} else {
+		y.parent.right = x
+	}
+
+	if y != z {
+		z.key = y.key
+		z.value = y.value
+	}
+
+	if y.color == BLACK {
+		tree.rbDeleteFixup(x, xparent)
+	}
+	tree.size--
+}
+
+func (tree *RbTree) rbDeleteFixup(x, parent *Node) {
+	var w *Node
+	for x != tree.root && getColor(x) == BLACK {
+		if x != nil {
+			parent = x.parent
+		}
+		if x == parent.left {
+			x, w = tree.rbFixupLeft(x, parent, w)
+		} else {
+			x, w = tree.rbFixupRight(x, parent, w)
+		}
+	}
+	if x != nil {
+		x.color = BLACK
+	}
+}
+
+func (tree *RbTree) rbFixupLeft(x, parent, w *Node) (*Node, *Node) {
+	w = parent.right
+	if w.color == RED {
+		w.color = BLACK
+		parent.color = RED
+		tree.leftRotate(parent)
+		w = parent.right
+	}
+	if getColor(w.left) == BLACK && getColor(w.right) == BLACK {
+		w.color = RED
+		x = parent
+	} else {
+		if getColor(w.right) == BLACK {
+			if w.left != nil {
+				w.left.color = BLACK
+			}
+			w.color = RED
+			tree.rightRotate(w)
+			w = parent.right
+		}
+		w.color = parent.color
+		parent.color = BLACK
+		if w.right != nil {
+			w.right.color = BLACK
+		}
+		tree.leftRotate(parent)
+		x = tree.root
+	}
+	return x, w
+}
+
+func (tree *RbTree) rbFixupRight(x, parent, w *Node) (*Node, *Node) {
+	w = parent.left
+	if w.color == RED {
+		w.color = BLACK
+		parent.color = RED
+		tree.rightRotate(parent)
+		w = parent.left
+	}
+	if getColor(w.left) == BLACK && getColor(w.right) == BLACK {
+		w.color = RED
+		x = parent
+	} else {
+		if getColor(w.left) == BLACK {
+			if w.right != nil {
+				w.right.color = BLACK
+			}
+			w.color = RED
+			tree.leftRotate(w)
+			w = parent.left
+		}
+		w.color = parent.color
+		parent.color = BLACK
+		if w.left != nil {
+			w.left.color = BLACK
+		}
+		tree.rightRotate(parent)
+		x = tree.root
+	}
+	return x, w
+}
+
+func (tree *RbTree) leftRotate(x *Node) {
+	y := x.right
+	x.right = y.left
+	if y.left != nil {
+		y.left.parent = x
+	}
+	y.parent = x.parent
+	if x.parent == nil {
+		tree.root = y
+	} else if x == x.parent.left {
+		x.parent.left = y
+	} else {
+		x.parent.right = y
+	}
+	y.left = x
+	x.parent = y
+}
+
+func (tree *RbTree) rightRotate(x *Node) {
+	y := x.left
+	x.left = y.right
+	if y.right != nil {
+		y.right.parent = x
+	}
+	y.parent = x.parent
+	if x.parent == nil {
+		tree.root = y
+	} else if x == x.parent.right {
+		x.parent.right = y
+	} else {
+		x.parent.left = y
+	}
+	y.right = x
+	x.parent = y
+}
+
+// findNode finds the node that its key is equal to the passed key, and returns it.
+func (tree *RbTree) findNode(key interface{}) *Node {
+	x := tree.root
+	for x != nil {
+		if tree.keyCmp(key, x.key) < 0 {
+			x = x.left
+		} else {
+			if tree.keyCmp(key, x.key) == 0 {
+				return x
+			}
+			x = x.right
+		}
+	}
+	return nil
+}
+
+// findNode finds the first node that its key is equal to the passed key, and returns it
+func (tree *RbTree) findFirstNode(key interface{}) *Node {
+	node := tree.FindLowerBoundNode(key)
+	if node == nil {
+		return nil
+	}
+	if tree.keyCmp(node.key, key) == 0 {
+		return node
+	}
+	return nil
+}
+
+// FindLowerBoundNode finds the first node that its key is equal or greater than the passed key, and returns it
+func (tree *RbTree) FindLowerBoundNode(key interface{}) *Node {
+	return tree.findLowerBoundNode(tree.root, key)
+}
+
+func (tree *RbTree) findLowerBoundNode(x *Node, key interface{}) *Node {
+	if x == nil {
+		return nil
+	}
+	if tree.keyCmp(key, x.key) <= 0 {
+		ret := tree.findLowerBoundNode(x.left, key)
+		if ret == nil {
+			return x
+		}
+		if tree.keyCmp(ret.key, x.key) <= 0 {
+			return ret
+		}
+		return x
+	}
+	return tree.findLowerBoundNode(x.right, key)
+}
+
+// FindUpperBoundNode finds the first node that its key is greater than the passed key, and returns it
+func (tree *RbTree) FindUpperBoundNode(key interface{}) *Node {
+	return tree.findUpperBoundNode(tree.root, key)
+}
+
+func (tree *RbTree) findUpperBoundNode(x *Node, key interface{}) *Node {
+	if x == nil {
+		return nil
+	}
+	if tree.keyCmp(key, x.key) >= 0 {
+		return tree.findUpperBoundNode(x.right, key)
+	}
+	ret := tree.findUpperBoundNode(x.left, key)
+	if ret == nil {
+		return x
+	}
+	if tree.keyCmp(ret.key, x.key) <= 0 {
+		return ret
+	}
+	return x
+}
+
+// Traversal traversals elements in the RbTree, it will not stop until to the end of RbTree or the visitor returns false
+func (tree *RbTree) Traversal(visitor visitor.KvVisitor) {
+	for node := tree.First(); node != nil; node = node.Next() {
+		if !visitor(node.key, node.value) {
+			break
+		}
+	}
+}
+
+// IsRbTree is a function use to test whether t is a RbTree or not
+func (tree *RbTree) IsRbTree() (bool, error) {
+	// Properties:
+	// 1. Each node is either red or black.
+	// 2. The root is black.
+	// 3. All leaves (NIL) are black.
+	// 4. If a node is red, then both its children are black.
+	// 5. Every path from a given node to any of its descendant NIL nodes contains the same number of black nodes.
+	_, property, ok := tree.test(tree.root)
+	if !ok {
+		return false, fmt.Errorf("violate property %v", property)
+	}
+	return true, nil
+}
+
+func (tree *RbTree) test(n *Node) (int, int, bool) {
+
+	if n == nil { // property 3:
+		return 1, 0, true
+	}
+
+	if n == tree.root && n.color != BLACK { // property 2:
+		return 1, 2, false
+	}
+	leftBlackCount, property, ok := tree.test(n.left)
+	if !ok {
+		return leftBlackCount, property, ok
+	}
+	rightBlackCount, property, ok := tree.test(n.right)
+	if !ok {
+		return rightBlackCount, property, ok
+	}
+
+	if rightBlackCount != leftBlackCount { // property 5:
+		return leftBlackCount, 5, false
+	}
+	blackCount := leftBlackCount
+
+	if n.color == RED {
+		if getColor(n.left) != BLACK || getColor(n.right) != BLACK { // property 4:
+			return 0, 4, false
+		}
+	} else {
+		blackCount++
+	}
+
+	if n == tree.root {
+		//fmt.Printf("blackCount:%v \n", blackCount)
+	}
+	return blackCount, 0, true
+}
+
+// getColor returns the node's color
+func getColor(n *Node) Color {
+	if n == nil {
+		return BLACK
+	}
+	return n.color
+}

+ 180 - 0
ext/ds/rbtree/rbtree_test.go

@@ -0,0 +1,180 @@
+package rbtree
+
+import (
+	"github.com/stretchr/testify/assert"
+	"math/rand"
+	"testing"
+	"time"
+	"ylink/ext/utils/comparator"
+)
+
+func TestRbTeeFind(t *testing.T) {
+	tree := New()
+	for i := 0; i < 10; i++ {
+		tree.Insert(i, i+10000)
+	}
+	assert.False(t, tree.Empty())
+	assert.Equal(t, 10, tree.Size())
+
+	for i := 0; i < 10; i++ {
+		val := tree.Find(i)
+		assert.Equal(t, i+10000, val)
+	}
+	for i := 0; i < 10; i++ {
+		iter := tree.FindLowerBoundNode(i)
+		assert.Equal(t, i+10000, iter.Value())
+
+		iter2 := tree.FindUpperBoundNode(i - 1)
+		assert.Equal(t, i+10000, iter2.Value())
+	}
+	for i := 0; i < 10; i++ {
+		tree.Insert(i, i+20000)
+	}
+
+	for i := 0; i < 10; i++ {
+		iter := tree.FindLowerBoundNode(i)
+		count := 0
+		for n := iter; n != nil; n = n.Next() {
+			if n.key != i {
+				break
+			}
+			count++
+			//t.Logf("travesal: %v = %v ", n.key, n.value)
+		}
+		assert.Equal(t, 2, count)
+	}
+
+	for i := 0; i < 10; i++ {
+		iter := tree.FindUpperBoundNode(i - 1)
+		count := 0
+		for n := iter; n != nil; n = n.Next() {
+			if n.key != i {
+				break
+			}
+			count++
+			//t.Logf("travesal: %v = %v ", n.key, n.value)
+		}
+		assert.Equal(t, 2, count)
+	}
+}
+
+func TestRbTeeDelete(t *testing.T) {
+	tree := New()
+	m := make(map[int]int)
+	for i := 0; i < 1000; i++ {
+		tree.Insert(i, i)
+		m[i] = i
+	}
+	count := 1000
+	for k, v := range m {
+		//t.Logf("%v", k)
+		node := tree.FindNode(k)
+		assert.Equal(t, v, node.Value())
+		tree.Delete(node)
+		assert.Nil(t, tree.FindNode(k))
+		count--
+		assert.Equal(t, count, tree.Size())
+	}
+}
+
+func TestTraversal(t *testing.T) {
+	tree := New()
+	for i := 0; i < 10; i++ {
+		tree.Insert(i, i+100)
+	}
+	i := 0
+	tree.Traversal(func(key, value interface{}) bool {
+		assert.Equal(t, i, key.(int))
+		assert.Equal(t, i+100, value.(int))
+		i++
+		return true
+	})
+}
+
+func TestInsertDelete(t *testing.T) {
+	tree := New()
+	m := make(map[int]int)
+	rand.Seed(time.Now().Unix())
+	for i := 0; i < 10000; i++ {
+		key := rand.Int() % 1000
+		val := rand.Int()
+		if v, ok := m[key]; ok {
+			n := tree.findNode(key)
+			assert.Equal(t, v, n.Value())
+			delete(m, key)
+			tree.Delete(n)
+		} else {
+			n := tree.findNode(key)
+			assert.Nil(t, n)
+
+			m[key] = val
+			tree.Insert(key, val)
+		}
+		assert.Equal(t, len(m), tree.Size())
+		b, _ := tree.IsRbTree()
+		assert.True(t, b)
+	}
+	tree.Clear()
+	assert.Equal(t, 0, tree.Size())
+}
+
+func TestIterator(t *testing.T) {
+	tree := New(WithKeyComparator(comparator.IntComparator))
+	for i := 0; i < 10; i++ {
+		tree.Insert(i, i+100)
+	}
+
+	i := 0
+	for iter := tree.IterFirst().Clone().(*RbTreeIterator); iter.IsValid(); iter.Next() {
+		assert.Equal(t, i, iter.Key())
+		assert.Equal(t, i+100, iter.Value())
+		i++
+	}
+
+	i = 9
+	for iter := tree.IterLast(); iter.IsValid(); iter.Prev() {
+		assert.Equal(t, i, iter.Key())
+		assert.Equal(t, i+100, iter.Value())
+		iter.SetValue(i * 2)
+		i--
+	}
+
+	i = 0
+	for iter := tree.IterFirst(); iter.IsValid(); iter.Next() {
+		assert.Equal(t, i, iter.Key())
+		assert.Equal(t, i*2, iter.Value())
+		i++
+	}
+	assert.True(t, tree.IterFirst().Equal(tree.IterFirst().Clone()))
+	assert.False(t, tree.IterFirst().Equal(nil))
+	assert.False(t, tree.IterFirst().Equal(tree.IterLast()))
+}
+
+func TestNode(t *testing.T) {
+	tree := New()
+	for i := 0; i < 10; i++ {
+		tree.Insert(i, i+100)
+	}
+
+	i := 0
+	for n := tree.Begin(); n != nil; n = n.Next() {
+		assert.Equal(t, i, n.Key())
+		assert.Equal(t, i+100, n.Value())
+		i++
+	}
+
+	i = 9
+	for n := tree.RBegin(); n != nil; n = n.Prev() {
+		assert.Equal(t, i, n.Key())
+		assert.Equal(t, i+100, n.Value())
+		n.SetValue(i * 2)
+		i--
+	}
+
+	i = 0
+	for n := tree.Begin(); n != nil; n = n.Next() {
+		assert.Equal(t, i, n.Key())
+		assert.Equal(t, i*2, n.Value())
+		i++
+	}
+}

+ 70 - 0
ext/ds/treemap/iterator.go

@@ -0,0 +1,70 @@
+//@File     iterator.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package treemap
+
+import (
+	"ylink/ext/ds/rbtree"
+	"ylink/ext/utils/iterator"
+)
+
+type MapIterator struct {
+	node *rbtree.Node
+}
+
+// IsValid returns true if the iterator is valid, otherwise returns false
+func (iter *MapIterator) IsValid() bool {
+	if iter.node != nil {
+		return true
+	}
+	return false
+}
+
+// Next moves the pointer of the iterator to the next node, and returns itself
+func (iter *MapIterator) Next() iterator.ConstIterator {
+	if iter.IsValid() {
+		iter.node = iter.node.Next()
+	}
+	return iter
+}
+
+// Prev moves the pointer of the iterator to the previous node, and returns itseft
+func (iter *MapIterator) Prev() iterator.ConstBidIterator {
+	if iter.IsValid() {
+		iter.node = iter.node.Prev()
+	}
+	return iter
+}
+
+// Key returns the node's key of the iterator point to
+func (iter *MapIterator) Key() interface{} {
+	return iter.node.Key()
+}
+
+// Value returns the node's value of the iterator point to
+func (iter *MapIterator) Value() interface{} {
+	return iter.node.Value()
+}
+
+// SetValue sets the node's value of the iterator point to
+func (iter *MapIterator) SetValue(val interface{}) {
+	iter.node.SetValue(val)
+}
+
+// Clone clones the iterator to a new MapIterator
+func (iter *MapIterator) Clone() iterator.ConstIterator {
+	return &MapIterator{iter.node}
+}
+
+// Equal returns true if the iterator is equal to the passed iterator, otherwise returns false
+func (iter *MapIterator) Equal(other iterator.ConstIterator) bool {
+	otherIter, ok := other.(*MapIterator)
+	if !ok {
+		return false
+	}
+	if otherIter.node == iter.node {
+		return true
+	}
+	return false
+}

+ 193 - 0
ext/ds/treemap/map.go

@@ -0,0 +1,193 @@
+//@File     map.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package treemap
+
+import (
+	gosync "sync"
+	"ylink/ext/ds/rbtree"
+	"ylink/ext/utils/comparator"
+	"ylink/ext/utils/iterator"
+	"ylink/ext/utils/sync"
+	"ylink/ext/utils/visitor"
+)
+
+var (
+	defaultKeyComparator = comparator.BuiltinTypeComparator
+	defaultLocker        sync.FakeLocker
+)
+
+type Options struct {
+	keyCmp comparator.Comparator
+	locker sync.Locker
+}
+
+// Option is a function type used to set Options
+type Option func(option *Options)
+
+// WithKeyComparator is used to set the key comparator of map
+func WithKeyComparator(cmp comparator.Comparator) Option {
+	return func(option *Options) {
+		option.keyCmp = cmp
+	}
+}
+
+func WithGoroutineSafe() Option {
+	return func(option *Options) {
+		option.locker = &gosync.RWMutex{}
+	}
+}
+
+// Map uses RbTress for internal data structure, and every key can must bee unique.
+type Map struct {
+	tree   *rbtree.RbTree
+	locker sync.Locker
+}
+
+// New creates a new map
+func New(opts ...Option) *Map {
+	option := Options{
+		keyCmp: defaultKeyComparator,
+		locker: defaultLocker,
+	}
+	for _, opt := range opts {
+		opt(&option)
+	}
+	return &Map{tree: rbtree.New(rbtree.WithKeyComparator(option.keyCmp)),
+		locker: option.locker,
+	}
+}
+
+//Insert inserts a key-value to the map
+func (m *Map) Insert(key, value interface{}) {
+	m.locker.Lock()
+	defer m.locker.Unlock()
+
+	node := m.tree.FindNode(key)
+	if node != nil {
+		node.SetValue(value)
+		return
+	}
+	m.tree.Insert(key, value)
+}
+
+//Get returns the value of the passed key if the key is in the map, otherwise returns nil
+func (m *Map) Get(key interface{}) interface{} {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	node := m.tree.FindNode(key)
+	if node != nil {
+		return node.Value()
+	}
+	return nil
+}
+
+//Erase erases the node by the passed key from the map if the key in the Map
+func (m *Map) Erase(key interface{}) {
+	m.locker.Lock()
+	defer m.locker.Unlock()
+
+	node := m.tree.FindNode(key)
+	if node != nil {
+		m.tree.Delete(node)
+	}
+}
+
+//EraseIter erases the node that iterator iter point to from the map
+func (m *Map) EraseIter(iter iterator.ConstKvIterator) {
+	m.locker.Lock()
+	defer m.locker.Unlock()
+
+	mpIter, ok := iter.(*MapIterator)
+	if ok {
+		m.tree.Delete(mpIter.node)
+	}
+}
+
+//Find finds a node by the passed key and returns its iterator
+func (m *Map) Find(key interface{}) *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	node := m.tree.FindNode(key)
+	return &MapIterator{node: node}
+}
+
+//LowerBound finds a node that its key is equal or greater than the passed key and returns its iterator
+func (m *Map) LowerBound(key interface{}) *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	node := m.tree.FindLowerBoundNode(key)
+	return &MapIterator{node: node}
+}
+
+//UpperBound finds a node that its key is greater than the passed key and returns its iterator
+func (m *Map) UpperBound(key interface{}) *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	node := m.tree.FindUpperBoundNode(key)
+	return &MapIterator{node: node}
+}
+
+//Begin returns the first node's iterator
+func (m *Map) Begin() *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	return &MapIterator{node: m.tree.First()}
+}
+
+//First returns the first node's iterator
+func (m *Map) First() *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	return &MapIterator{node: m.tree.First()}
+}
+
+//Last returns the last node's iterator
+func (m *Map) Last() *MapIterator {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	return &MapIterator{node: m.tree.Last()}
+}
+
+//Clear clears the map
+func (m *Map) Clear() {
+	m.locker.Lock()
+	defer m.locker.Unlock()
+
+	m.tree.Clear()
+}
+
+// Contains returns true if the key is in the map. otherwise returns false.
+func (m *Map) Contains(key interface{}) bool {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	if m.tree.Find(key) != nil {
+		return true
+	}
+	return false
+}
+
+// Size returns the amount of elements in the map
+func (m *Map) Size() int {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	return m.tree.Size()
+}
+
+// Traversal traversals elements in the map, it will not stop until to the end or the visitor returns false
+func (m *Map) Traversal(visitor visitor.KvVisitor) {
+	m.locker.RLock()
+	defer m.locker.RUnlock()
+
+	m.tree.Traversal(visitor)
+}

+ 94 - 0
ext/ds/treemap/map_test.go

@@ -0,0 +1,94 @@
+package treemap
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestMap(t *testing.T) {
+	m := New()
+
+	assert.Equal(t, 0, m.Size())
+	assert.False(t, m.Contains(5))
+	assert.Equal(t, nil, m.Get(3))
+
+	for i := 9; i >= 0; i-- {
+		m.Insert(i, i+1000)
+	}
+
+	assert.Equal(t, 10, m.Size())
+	assert.True(t, m.Contains(5))
+	assert.Equal(t, 3+1000, m.Get(3))
+	m.Erase(3)
+	assert.Equal(t, nil, m.Get(3))
+	m.Clear()
+	assert.False(t, m.Contains(50))
+	assert.Equal(t, 0, m.Size())
+}
+
+func TestMapIterator(t *testing.T) {
+	m := New(WithGoroutineSafe())
+
+	for i := 1; i <= 10; i++ {
+		m.Insert(i, i)
+	}
+
+	i := 1
+	for iter := m.First(); iter.IsValid(); iter.Next() {
+		assert.Equal(t, i, iter.Value().(int))
+		i++
+	}
+
+	i = 10
+	for iter := m.Last().Clone().(*MapIterator); iter.IsValid(); iter.Prev() {
+		assert.Equal(t, i, iter.Value().(int))
+		i--
+	}
+
+	assert.True(t, m.Begin().Equal(m.First()))
+
+	iter := m.Find(8)
+	assert.Equal(t, 8, iter.Key().(int))
+	assert.Equal(t, 8, iter.Value().(int))
+
+	iter = m.LowerBound(8)
+	assert.Equal(t, 8, iter.Value().(int))
+
+	iter = m.UpperBound(6)
+	assert.Equal(t, 7, iter.Value().(int))
+
+	m.EraseIter(iter)
+	assert.False(t, m.Contains(7))
+}
+
+func TestMapIteratorSetValue(t *testing.T) {
+	m := New(WithGoroutineSafe())
+	m.Insert(1, "aaa")
+	m.Insert(2, "bbb")
+	m.Insert(3, "hhh")
+
+	assert.Equal(t, "aaa", m.Get(1))
+
+	iter := m.Find(1)
+
+	assert.Equal(t, "aaa", iter.Value())
+
+	iter.SetValue("ccc")
+	assert.Equal(t, "ccc", m.Get(1))
+}
+
+func TestMap_Traversal(t *testing.T) {
+	m := New()
+
+	for i := 1; i <= 5; i++ {
+		m.Insert(i, i+1000)
+	}
+
+	i := 1
+	m.Traversal(func(key, value interface{}) bool {
+		assert.Equal(t, i, key)
+		assert.Equal(t, i+1000, value)
+		i++
+		return true
+	})
+}

+ 153 - 0
ext/ds/treemap/multimap.go

@@ -0,0 +1,153 @@
+//@File     multimap.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+package treemap
+
+import (
+	"ylink/ext/ds/rbtree"
+	"ylink/ext/utils/comparator"
+	"ylink/ext/utils/sync"
+	"ylink/ext/utils/visitor"
+)
+
+// MultiMap uses RbTress for internal data structure, and keys can bee repeated.
+type MultiMap struct {
+	tree   *rbtree.RbTree
+	keyCmp comparator.Comparator
+	locker sync.Locker
+}
+
+//NewMultiMap creates a new MultiMap
+func NewMultiMap(opts ...Option) *MultiMap {
+	option := Options{
+		keyCmp: defaultKeyComparator,
+		locker: defaultLocker,
+	}
+	for _, opt := range opts {
+		opt(&option)
+	}
+	return &MultiMap{tree: rbtree.New(rbtree.WithKeyComparator(option.keyCmp)),
+		keyCmp: option.keyCmp,
+		locker: option.locker,
+	}
+}
+
+//Insert inserts a key-value to the MultiMap
+func (mm *MultiMap) Insert(key, value interface{}) {
+	mm.locker.Lock()
+	defer mm.locker.Unlock()
+
+	mm.tree.Insert(key, value)
+}
+
+//Get returns the first node's value by the passed key if the key is in the MultiMap, otherwise returns nil
+func (mm *MultiMap) Get(key interface{}) interface{} {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	node := mm.tree.FindNode(key)
+	if node != nil {
+		return node.Value()
+	}
+	return nil
+}
+
+//Erase erases the key in the MultiMap
+func (mm *MultiMap) Erase(key interface{}) {
+	mm.locker.Lock()
+	defer mm.locker.Unlock()
+
+	for {
+		node := mm.tree.FindNode(key)
+		if node == nil {
+			break
+		}
+		mm.tree.Delete(node)
+	}
+}
+
+//Find finds the node by the passed key in the MultiMap and returns its iterator
+func (mm *MultiMap) Find(key interface{}) *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	node := mm.tree.FindNode(key)
+	return &MapIterator{node: node}
+}
+
+//LowerBound find the first node that its key is equal or greater than the passed key in the MultiMap, and returns its iterator
+func (mm *MultiMap) LowerBound(key interface{}) *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	node := mm.tree.FindLowerBoundNode(key)
+	return &MapIterator{node: node}
+}
+
+//UpperBound find the first node that its key is greater than the passed key in the MultiMap, and returns its iterator
+func (mm *MultiMap) UpperBound(key interface{}) *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	node := mm.tree.FindUpperBoundNode(key)
+	return &MapIterator{node: node}
+}
+
+//Begin returns the first node's iterator
+func (mm *MultiMap) Begin() *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	return &MapIterator{node: mm.tree.First()}
+}
+
+//First returns the first node's iterator
+func (mm *MultiMap) First() *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	return &MapIterator{node: mm.tree.First()}
+}
+
+//Last returns the last node's iterator
+func (mm *MultiMap) Last() *MapIterator {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	return &MapIterator{node: mm.tree.Last()}
+}
+
+//Clear clears the MultiMap
+func (mm *MultiMap) Clear() {
+	mm.locker.Lock()
+	defer mm.locker.Unlock()
+
+	mm.tree.Clear()
+}
+
+// Contains returns true if the passed value is in the MultiMap. otherwise returns false.
+func (mm *MultiMap) Contains(value interface{}) bool {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	if mm.tree.Find(value) != nil {
+		return true
+	}
+	return false
+}
+
+// Size returns the amount of elements in the MultiMap
+func (mm *MultiMap) Size() int {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	return mm.tree.Size()
+}
+
+// Traversal traversals elements in the MultiMap, it will not stop until to the end of the MultiMap or the visitor returns false
+func (mm *MultiMap) Traversal(visitor visitor.KvVisitor) {
+	mm.locker.RLock()
+	defer mm.locker.RUnlock()
+
+	mm.tree.Traversal(visitor)
+}

+ 82 - 0
ext/ds/treemap/multimap_test.go

@@ -0,0 +1,82 @@
+package treemap
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestMultiMap(t *testing.T) {
+	m := NewMultiMap()
+
+	assert.Equal(t, 0, m.Size())
+	assert.False(t, m.Contains(5))
+	assert.Equal(t, nil, m.Get(3))
+
+	for i := 9; i >= 0; i-- {
+		m.Insert(i, i+1000)
+	}
+
+	assert.Equal(t, 10, m.Size())
+	assert.True(t, m.Contains(5))
+	assert.Equal(t, 3+1000, m.Get(3))
+	m.Erase(3)
+	assert.Equal(t, nil, m.Get(3))
+	m.Clear()
+	assert.False(t, m.Contains(50))
+	assert.Equal(t, 0, m.Size())
+}
+
+func TestMultiMapIterator(t *testing.T) {
+	m := NewMultiMap(WithGoroutineSafe())
+
+	for i := 1; i <= 10; i++ {
+		m.Insert(i, i)
+	}
+
+	i := 1
+	for iter := m.First(); iter.IsValid(); iter.Next() {
+		assert.Equal(t, i, iter.Value().(int))
+		i++
+	}
+
+	i = 10
+	for iter := m.Last(); iter.IsValid(); iter.Prev() {
+		assert.Equal(t, i, iter.Value().(int))
+		i--
+	}
+
+	assert.True(t, m.Begin().Equal(m.First()))
+
+	iter := m.Find(8)
+	assert.Equal(t, 8, iter.Value().(int))
+
+	iter = m.LowerBound(8)
+	assert.Equal(t, 8, iter.Value().(int))
+
+	iter = m.UpperBound(5)
+	assert.Equal(t, 6, iter.Value().(int))
+}
+
+func TestMultiMap_Traversal(t *testing.T) {
+	m := NewMultiMap()
+
+	for i := 1; i <= 5; i++ {
+		m.Insert(i, i+1000)
+	}
+
+	for i := 1; i <= 5; i++ {
+		m.Insert(i, i+1000)
+	}
+
+	i := 1
+	count := 0
+	m.Traversal(func(key, value interface{}) bool {
+		assert.Equal(t, i, key)
+		assert.Equal(t, i+1000, value)
+		count++
+		if count%2 == 0 {
+			i++
+		}
+		return true
+	})
+}

+ 13 - 0
ext/model/csinfo.go

@@ -0,0 +1,13 @@
+//@File     csinfo.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package model
+
+type CsInfo struct {
+	CsId         string `json:"cs_id"`
+	CsNickname   string `json:"cs_nickname"`
+	CsAvatarUrl  string `json:"cs_avatar_url"`
+	CsSignature  string `json:"cs_signature"`
+	OnlineStatus int64  `json:"online_status"`
+}

+ 1 - 0
ext/model/message.go

@@ -10,4 +10,5 @@ type ChatMessage struct {
 	Pic        string `json:"pic"`
 	ReceiverId string `json:"receiver_id"`
 	SenderId   string `json:"sender_id"`
+	GameId     string `json:"game_id"`
 }

+ 379 - 0
ext/utils/comparator/comparator.go

@@ -0,0 +1,379 @@
+//@File     comparator.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package comparator
+
+// Comparator Should return a number:
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+type Comparator func(a, b interface{}) int
+
+// BuiltinTypeComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+// make sure a and b are both builtin type
+func BuiltinTypeComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	switch a.(type) {
+	case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, uintptr:
+		return cmpInt(a, b)
+	case float32:
+		if a.(float32) < b.(float32) {
+			return -1
+		}
+	case float64:
+		if a.(float64) < b.(float64) {
+			return -1
+		}
+	case bool:
+		if a.(bool) == false && b.(bool) == true {
+			return -1
+		}
+	case string:
+		if a.(string) < b.(string) {
+			return -1
+		}
+	case complex64:
+		return cmpComplex64(a.(complex64), b.(complex64))
+	case complex128:
+		return cmpComplex128(a.(complex128), b.(complex128))
+	}
+	return 1
+}
+
+func cmpInt(a, b interface{}) int {
+	switch a.(type) {
+	case int:
+		return cmpInt64(int64(a.(int)), int64(b.(int)))
+	case uint:
+		return cmpUint64(uint64(a.(uint)), uint64(b.(uint)))
+	case int8:
+		return cmpInt64(int64(a.(int8)), int64(b.(int8)))
+	case uint8:
+		return cmpUint64(uint64(a.(uint8)), uint64(b.(uint8)))
+	case int16:
+		return cmpInt64(int64(a.(int16)), int64(b.(int16)))
+	case uint16:
+		return cmpUint64(uint64(a.(uint16)), uint64(b.(uint16)))
+	case int32:
+		return cmpInt64(int64(a.(int32)), int64(b.(int32)))
+	case uint32:
+		return cmpUint64(uint64(a.(uint32)), uint64(b.(uint32)))
+	case int64:
+		return cmpInt64(a.(int64), b.(int64))
+	case uint64:
+		return cmpUint64(a.(uint64), b.(uint64))
+	case uintptr:
+		return cmpUint64(uint64(a.(uintptr)), uint64(b.(uintptr)))
+	}
+
+	return 0
+}
+
+func cmpInt64(a, b int64) int {
+	if a < b {
+		return -1
+	}
+	return 1
+}
+
+func cmpUint64(a, b uint64) int {
+	if a < b {
+		return -1
+	}
+	return 1
+}
+
+func cmpFloat32(a, b float32) int {
+	if a < b {
+		return -1
+	}
+	return 1
+}
+
+func cmpFloat64(a, b float64) int {
+	if a < b {
+		return -1
+	}
+	return 1
+}
+
+func cmpComplex64(a, b complex64) int {
+	if real(a) < real(b) {
+		return -1
+	}
+	if real(a) == real(b) && imag(a) < imag(b) {
+		return -1
+	}
+	return 1
+}
+
+func cmpComplex128(a, b complex128) int {
+	if real(a) < real(b) {
+		return -1
+	}
+	if real(a) == real(b) && imag(a) < imag(b) {
+		return -1
+	}
+	return 1
+}
+
+//Reverse returns a comparator reverse to cmp
+func Reverse(cmp Comparator) Comparator {
+	return func(a, b interface{}) int {
+		return -cmp(a, b)
+	}
+}
+
+// IntComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func IntComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(int) < b.(int) {
+		return -1
+	}
+	return 1
+}
+
+// UintComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func UintComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uint) < b.(uint) {
+		return -1
+	}
+	return 1
+}
+
+// Int8Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Int8Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(int8) < b.(int8) {
+		return -1
+	}
+	return 1
+}
+
+// Uint8Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Uint8Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uint8) < b.(uint8) {
+		return -1
+	}
+	return 1
+}
+
+// Int16Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Int16Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(int16) < b.(int16) {
+		return -1
+	}
+	return 1
+}
+
+// Uint16Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Uint16Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uint16) < b.(uint16) {
+		return -1
+	}
+	return 1
+}
+
+// Int32Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Int32Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(int32) < b.(int32) {
+		return -1
+	}
+	return 1
+}
+
+// Uint32Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Uint32Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uint32) < b.(uint32) {
+		return -1
+	}
+	return 1
+}
+
+// Int64Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Int64Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(int64) < b.(int64) {
+		return -1
+	}
+	return 1
+}
+
+// Uint64Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Uint64Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uint64) < b.(uint64) {
+		return -1
+	}
+	return 1
+}
+
+// Float32Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Float32Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(float32) < b.(float32) {
+		return -1
+	}
+	return 1
+}
+
+// Float64Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Float64Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(float64) < b.(float64) {
+		return -1
+	}
+	return 1
+}
+
+// StringComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func StringComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(string) < b.(string) {
+		return -1
+	}
+	return 1
+}
+
+// UintptrComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func UintptrComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(uintptr) < b.(uintptr) {
+		return -1
+	}
+	return 1
+}
+
+// BoolComparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func BoolComparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	if a.(bool) == false && b.(bool) == true {
+		return -1
+	}
+	return 1
+}
+
+// Complex64Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Complex64Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	comA := a.(complex64)
+	comB := b.(complex64)
+	if real(comA) < real(comB) {
+		return -1
+	}
+	if real(comA) == real(comB) && imag(comA) < imag(comB) {
+		return -1
+	}
+	return 1
+}
+
+// Complex128Comparator compare a with b
+//    -1 , if a < b
+//    0  , if a == b
+//    1  , if a > b
+func Complex128Comparator(a, b interface{}) int {
+	if a == b {
+		return 0
+	}
+	comA := a.(complex128)
+	comB := b.(complex128)
+	if real(comA) < real(comB) {
+		return -1
+	}
+	if real(comA) == real(comB) && imag(comA) < imag(comB) {
+		return -1
+	}
+	return 1
+}

+ 64 - 0
ext/utils/iterator/iterator.go

@@ -0,0 +1,64 @@
+//@File     iterator.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package iterator
+
+type ConstIterator interface {
+	IsValid() bool
+	Next() ConstIterator
+	Value() interface{}
+	Clone() ConstIterator
+	Equal(other ConstIterator) bool
+}
+
+// Iterator is an interface of mutable iterator
+type Iterator interface {
+	ConstIterator
+	SetValue(value interface{})
+}
+
+// ConstKvIterator is an interface of const key-value type iterator
+type ConstKvIterator interface {
+	ConstIterator
+	Key() interface{}
+}
+
+// KvIterator is an interface of mutable key-value type iterator
+type KvIterator interface {
+	ConstKvIterator
+	SetValue(value interface{})
+}
+
+// ConstBidIterator is an interface of const bidirectional iterator
+type ConstBidIterator interface {
+	ConstIterator
+	Prev() ConstBidIterator
+}
+
+// BidIterator is an interface of mutable bidirectional iterator
+type BidIterator interface {
+	ConstBidIterator
+	SetValue(value interface{})
+}
+
+// ConstKvBidIterator is an interface of const key-value type bidirectional iterator
+type ConstKvBidIterator interface {
+	ConstKvIterator
+	Prev() ConstBidIterator
+}
+
+// KvBidIterator is an interface of mutable key-value type bidirectional iterator
+type KvBidIterator interface {
+	ConstKvIterator
+	Prev() ConstBidIterator
+	SetValue(value interface{})
+}
+
+// RandomAccessIterator is an interface of mutable random access iterator
+type RandomAccessIterator interface {
+	BidIterator
+	//IteratorAt returns a new iterator at position
+	IteratorAt(position int) RandomAccessIterator
+	Position() int
+}

+ 39 - 0
ext/utils/sync/locker.go

@@ -0,0 +1,39 @@
+//@File     locker.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package sync
+
+import gosync "sync"
+
+type Locker interface {
+	Lock()
+	Unlock()
+	RLock()
+	RUnlock()
+}
+
+var _ Locker = (*gosync.RWMutex)(nil)
+
+type FakeLocker struct {
+}
+
+// Lock does nothing
+func (l FakeLocker) Lock() {
+
+}
+
+// Unlock does nothing
+func (l FakeLocker) Unlock() {
+
+}
+
+// RLock does nothing
+func (l FakeLocker) RLock() {
+
+}
+
+// RUnlock does nothing
+func (l FakeLocker) RUnlock() {
+
+}

+ 9 - 0
ext/utils/visitor/visitor.go

@@ -0,0 +1,9 @@
+//@File     visitor.go
+//@Time     2022/05/12
+//@Author   #Suyghur,
+
+package visitor
+
+type Visitor func(value interface{}) bool
+
+type KvVisitor func(key, value interface{}) bool

+ 4 - 4
flowsrv/rpc/etc/flowsrv.yaml

@@ -3,7 +3,7 @@ ListenOn: 0.0.0.0:10200
 
 Etcd:
   Hosts:
-    - 127.0.0.1:2379
+    - localhost:2379
   Key: flowsrv.rpc
 
 Telemetry:
@@ -15,11 +15,11 @@ Telemetry:
 AuthRpcConf:
   Etcd:
     Hosts:
-      - 127.0.0.1:2379
+      - localhost:2379
     Key: auth.rpc
 
-KqMsgConf:
+KqRecvMsgConf:
   Brokers:
-    - 127.0.0.1:9092
+    - localhost:9092
   Topic: recv-box-topic
   GroupId: flowsrv

+ 1 - 1
flowsrv/rpc/internal/logic/connectlogic.go

@@ -29,7 +29,7 @@ func (l *ConnectLogic) Connect(in *pb.CommandReq, stream pb.Flowsrv_ConnectServe
 	_, err := l.svcCtx.AuthRpc.CheckAuth(l.ctx, &auth.CheckAuthReq{
 		AccessToken: in.AccessToken,
 	})
-	//data, _ := structpb.NewStruct(map[string]interface{}{})
+	//data, _ := structpb.NewStruct(treemap[string]interface{}{})
 	if err != nil {
 		return stream.Send(&pb.CommandResp{
 			Code: result.TokenParseError,

+ 1 - 1
flowsrv/rpc/internal/logic/disconnectlogic.go

@@ -29,7 +29,7 @@ func (l *DisconnectLogic) Disconnect(in *pb.CommandReq) (*pb.CommandResp, error)
 	_, err := l.svcCtx.AuthRpc.CheckAuth(l.ctx, &auth.CheckAuthReq{
 		AccessToken: in.AccessToken,
 	})
-	//data, _ := structpb.NewStruct(map[string]interface{}{})
+	//data, _ := structpb.NewStruct(treemap[string]interface{}{})
 	if err != nil {
 		return &pb.CommandResp{
 			Code: result.TokenParseError,

+ 3 - 0
go.mod

@@ -6,6 +6,7 @@ require (
 	github.com/Shopify/sarama v1.32.0
 	github.com/golang-jwt/jwt/v4 v4.4.1
 	github.com/pkg/errors v0.9.1
+	github.com/stretchr/testify v1.7.0
 	github.com/zeromicro/go-zero v1.3.3
 	google.golang.org/grpc v1.46.0
 	google.golang.org/protobuf v1.28.0
@@ -47,6 +48,7 @@ require (
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/openzipkin/zipkin-go v0.4.0 // indirect
 	github.com/pierrec/lz4 v2.6.1+incompatible // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/prometheus/client_golang v1.11.0 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
 	github.com/prometheus/common v0.30.0 // indirect
@@ -76,6 +78,7 @@ require (
 	google.golang.org/genproto v0.0.0-20220422154200-b37d22cd5731 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 	k8s.io/api v0.20.12 // indirect
 	k8s.io/apimachinery v0.20.12 // indirect
 	k8s.io/client-go v0.20.12 // indirect

+ 0 - 2
go.sum

@@ -204,8 +204,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E=
-github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=

+ 0 - 9
inner/rpc/pb/inner.proto

@@ -1,9 +0,0 @@
-syntax = "proto3";
-
-option go_package = "./pb";
-
-package pb;
-
-
-service Inner {
-}

Неке датотеке нису приказане због велике количине промена