diff --git a/common/data/entity/Client.go b/common/data/entity/Client.go index c8a69d2ec..6f02f595b 100644 --- a/common/data/entity/Client.go +++ b/common/data/entity/Client.go @@ -1,15 +1,41 @@ package entity +import "sync" + type ClientData struct { - IsCrossDomain bool //是否跨域过 - Player *Player //客户实体 + isCrossDomain bool //是否跨域过 + player *Player //客户实体 + //UserID uint32 + m sync.Mutex +} + +func (cd *ClientData) SetPlayer(player *Player) { + cd.m.Lock() + defer cd.m.Unlock() + cd.player = player +} +func (cd *ClientData) GetPlayer() *Player { + cd.m.Lock() + defer cd.m.Unlock() + return cd.player +} +func (cd *ClientData) SetCrossDomain(isCrossDomain bool) { + cd.m.Lock() + defer cd.m.Unlock() + cd.isCrossDomain = isCrossDomain +} +func (cd *ClientData) GetIsCrossDomain() bool { + cd.m.Lock() + defer cd.m.Unlock() + return cd.isCrossDomain } func NewClientData() *ClientData { - cd := &ClientData{ - IsCrossDomain: false, - Player: nil, + cd := ClientData{ + isCrossDomain: false, + player: nil, + m: sync.Mutex{}, } - return cd + return &cd } diff --git a/common/data/entity/player.go b/common/data/entity/player.go index d6b75e904..e4e31dd92 100644 --- a/common/data/entity/player.go +++ b/common/data/entity/player.go @@ -1,6 +1,8 @@ package entity import ( + "blazing/common/core" + "github.com/panjf2000/gnet/v2" ) @@ -43,3 +45,16 @@ func (p *Player) SendPack(b []byte) error { _, err := p.MainConn.Write(b) return err } + +func ConutPlayer() int { + + // v := reflect.ValueOf(&core.Mainplayer).Elem().FieldByName("m").Elem() + // return int(v.FieldByName("count").Int()) + count := 0 + core.Mainplayer.Range(func(key, value interface{}) bool { + count++ + return true // 继续遍历 + }) + return count + //fmt.Println("元素数量:", count) // 输出: 3 +} diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go index 9f54ddd26..0fcb44e50 100644 --- a/common/rpc/rpc.go +++ b/common/rpc/rpc.go @@ -17,6 +17,7 @@ var usermap = make(map[int]int) //用户->客户端的map // Define the client handler interface type ClientHandler struct { KickPerson func(int) error //踢人,这里是返回具体的logic + QuitSelf func(int) error //关闭服务器进程 } // Define the server handler @@ -43,18 +44,30 @@ func (h *ServerHandler) Kick(ctx context.Context, userid int) error { } // 退出指定服务器 -func (h *ServerHandler) Quit(ctx context.Context, userid int) error { +// func (h *ServerHandler) Quit(ctx context.Context, portid int) error { - return nil +// a, ok := clientmap[portid] -} +// if ok && a != nil { +// a.QuitSelf(0) +// } +// //clientmap[portid].QuitSelf(0) +// return nil + +// } // 注册logic服务器 func (h *ServerHandler) RegisterLogic(ctx context.Context, port int) error { + //TODO 待修复滚动更新可能导致的玩家可以同时在旧服务器和新服务器同时在线的bug revClient, ok := jsonrpc.ExtractReverseClient[ClientHandler](ctx) if !ok { return fmt.Errorf("no reverse client") } + + aa, ok := clientmap[port] + if ok && aa != nil { + aa.QuitSelf(0) + } clientmap[port] = &revClient return nil @@ -92,8 +105,8 @@ func StartServer() { var closer jsonrpc.ClientCloser func StartClient(port uint16, callback any) *struct { - Kick func(int32) error - Quit func(int32) error + Kick func(int32) error + RegisterLogic func(int32) error UserLogin func(int32, int32) error UserLogout func(int32, int32) error @@ -124,8 +137,8 @@ func CloseClient() { // Setup RPCClient with reverse call handler var RPCClient struct { - Kick func(int32) error //踢人 - Quit func(int32) error //退出指定服务器 + Kick func(int32) error //踢人 + RegisterLogic func(int32) error //注册服务器消息 UserLogin func(int32, int32) error //用户登录事件 diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index 9c20e0788..02c216cf6 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -2,10 +2,12 @@ package socket import ( "context" + "fmt" "log" "blazing/common/data/entity" + "github.com/gogf/gf/v2/os/glog" "github.com/panjf2000/gnet/v2" "github.com/panjf2000/gnet/v2/pkg/logging" ) @@ -30,7 +32,17 @@ func (s *Server) Stop() error { func (s *Server) OnClose(c gnet.Conn, _ error) (action gnet.Action) { //fmt.Println(glog.GetStack(), c.Context().(*entity.ClientData).Player.UserID, "断开连接") + //fmt.Println("远程地址", c.RemoteAddr(), c) + fmt.Printf("关闭函数地址: %p\n", c.Context()) // 输出类似: 0x1040a1390 + //if c.Context() != nil { + v := c.Context().(*entity.ClientData) + t := v.GetPlayer() + if t != nil { + glog.Debug(context.Background(), t.UserID, "断开连接") + } + + //} //关闭连接 return } @@ -43,8 +55,10 @@ func (s *Server) OnBoot(eng gnet.Engine) gnet.Action { } func (s *Server) OnTraffic(conn gnet.Conn) (action gnet.Action) { + if conn.Context() == nil { + conn.SetContext(entity.NewClientData()) //注入data + } - conn.SetContext(entity.NewClientData()) //注入data if s.network == "tcp" { return s.handleTcp(conn) } @@ -100,7 +114,7 @@ const TEXT = "\x00" func handle(c gnet.Conn) { clientdata := c.Context().(*entity.ClientData) - if clientdata.IsCrossDomain { + if clientdata.GetIsCrossDomain() { return } @@ -117,7 +131,7 @@ func handle(c gnet.Conn) { c.Write([]byte(CROSS_DOMAIN)) c.Discard(len(TEXT)) - clientdata.IsCrossDomain = true //TODO 待修复未成功切换bug + clientdata.SetCrossDomain(true) //= true //TODO 待修复未成功切换bug return } diff --git a/logic/controller/controller.go b/logic/controller/controller.go index 79c4de40d..e8bc204c6 100644 --- a/logic/controller/controller.go +++ b/logic/controller/controller.go @@ -7,6 +7,7 @@ import ( "blazing/common/socket/handler" "blazing/cool" "blazing/logic/service" + "time" "bytes" "context" @@ -25,8 +26,8 @@ var Maincontroller = NewController() //注入service type Controller struct { Port uint32 RPCClient struct { - Kick func(int32) error - Quit func(int32) error + Kick func(int32) error + RegisterLogic func(int32) error UserLogin func(int32, int32) error UserLogout func(int32, int32) error @@ -34,11 +35,27 @@ type Controller struct { } func (h *Controller) KickPerson(a int) error { - //TODO 这里待实现踢人 + fmt.Println("检测到踢人请求", a) service.KickPlayer(uint32(a)) return nil } +func (h *Controller) QuitSelf(a int) error { + //TODO 这里待退出 + fmt.Println("检测到退出请求") + + go func() { + + for { + + //entity.ConutPlayer() + fmt.Println("当前在线人数", entity.ConutPlayer()) + <-time.After((1000)) + } + }() + //service.KickPlayer(uint32(a)) + return nil +} func NewController() *Controller { return &Controller{} } @@ -176,7 +193,8 @@ func Recv(c gnet.Conn, data handler.TomeeHeader) { params = append(params, ptrValue1, reflect.ValueOf(service.GetPlayer(c, data.UserID))) } else { - + // fmt.Println("远程地址", c.RemoteAddr(), c) + //c.SetContext("ahahha") params = append(params, ptrValue1, reflect.ValueOf(c)) } @@ -187,18 +205,5 @@ func Recv(c gnet.Conn, data handler.TomeeHeader) { if err != nil { fmt.Println(err) } - // switch ret[0].Interface().(type) { //TODO 待修改 - // case []byte: //原始包 - // c.Write(ret[0].Interface().([]byte)) //这里直接发送原始包,应该是已经拼接过的原始包,通常不同使用 - - // //case uint32: //错误码 实际上这里包含在结构体里了 ,错误码应该构造在返回之前 - - // default: - - // var data1 bytes.Buffer - // struc.Pack(&data1, &data) - // c.Write(data1.Bytes()) - - // } } diff --git a/logic/controller/login.go b/logic/controller/login.go index 251f95de1..2a0aff3b5 100644 --- a/logic/controller/login.go +++ b/logic/controller/login.go @@ -13,14 +13,17 @@ import ( // 处理命令: 1001 func (h *Controller) Login(data login.LoginSidInfo, c gnet.Conn) []byte { //这个时候player应该是空的 + //c := *c1 + //c.SetContext("ahahha") //fmt.Println(data.CheakSession()) //检查结构体 - + //fmt.Println("远程地址", c.RemoteAddr(), c) if tt := data.CheakSession(); tt { //说明sid正确 h.RPCClient.Kick(int32(data.Head.UserID)) //先踢人 - service.SetPlayer(c, data.Head.UserID) - h.RPCClient.UserLogin(int32(h.Port), int32(data.Head.UserID)) //初始化用户登录 + h.RPCClient.UserLogin(int32(h.Port), int32(data.Head.UserID)) //初始化用户登录 + service.SetPlayer(c, data.Head.UserID) } + t1, _ := hex.DecodeString("0000045D37000003E9000186A600000000000186A6683F89CF6E69656F0000000000000000000000000008000F00000000000000000000000000000000000000000000000000000001000001DB0000018B000000000000A8C000000000000000000000000000000000000000080001388000000001000000017FFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000000000000000000000064000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001FFFFFFFF000000004E4F4E4F0000000000000000000000000000000000000001000000010000000100000001000000010000000100000001000000000003030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000100000064000000000000000000000000000000000000001F000000000000006400000000000093F4000093F4000000D5000000F7000000AD00000088000000920000008C0000009C00000000000000000000000000000000000000000000000000000004000027900000001B00004E6200000014000028380000002800004E3E0000002368493DC60000000000000000000000000000000000000000000100000000000000A937000007D1000186A600000000000186A66E69656F00000000000000000000000000000000000000000000000F0000000000000000000001DB0000018B0000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0000000000000001000000000000000000000000000000000000000000000000000000000000000000000000") //t1 = t1[17:] fmt.Println(t1[:40]) diff --git a/logic/server.go b/logic/server.go index a06890955..1eaee018c 100644 --- a/logic/server.go +++ b/logic/server.go @@ -71,15 +71,15 @@ func Start(serverid uint32) { log.Fatalf("Failed to determine port: %v", err) } - go func() { - t := rpc.StartClient(uint16(serverid), controller.Maincontroller) + // go func() { + t := rpc.StartClient(uint16(serverid), controller.Maincontroller) - controller.Maincontroller.RPCClient = *t //将RPC赋值Start - controller.Maincontroller.Port = serverid //赋值服务器ID - }() + controller.Maincontroller.RPCClient = *t //将RPC赋值Start + controller.Maincontroller.Port = serverid //赋值服务器ID + //}() //go rpc.StartClient(uint16(serverid), &controller.Maincontroller) - service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port)) + service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port), t) socket.NewServer(socket.WithCORS(), socket.WithPort(port), socket.WithSocketHandler(head)).Start() } else { diff --git a/logic/service/service.go b/logic/service/service.go index 2d203409e..73371f334 100644 --- a/logic/service/service.go +++ b/logic/service/service.go @@ -5,6 +5,7 @@ import ( "blazing/common/data/entity" "blazing/common/socket/errorcode" "blazing/common/socket/handler" + "fmt" "github.com/panjf2000/gnet/v2" ) @@ -14,13 +15,13 @@ func GetPlayer(c gnet.Conn, userid uint32) *entity.Player { //TODO 这里待优 //检查player初始化,是否为conn初始后取map,防止二次连接后存在两个player clientdata := c.Context().(*entity.ClientData) - if clientdata != nil && clientdata.Player != nil { - return clientdata.Player + if clientdata.GetPlayer() != nil { + return clientdata.GetPlayer() } var player *entity.Player if player1, ok := core.Mainplayer.Load((userid)); ok { player = player1.(*entity.Player) //取成功,否则创建 - clientdata.Player = player + clientdata.SetPlayer(player) } return player @@ -44,15 +45,23 @@ func KickPlayer(userid uint32) { //踢出玩家 //return player // return nil } -func SetPlayer(c gnet.Conn, userid uint32) *entity.Player { //TODO 这里待优化,可能存在内存泄漏问题 +func SetPlayer(c gnet.Conn, userid uint32) *entity.Player { //TODO 这里待优化, + //c.RemoteAddr() + //g.Dump(c) + //fmt.Println("远程地址", c.RemoteAddr(), c) + fmt.Printf("设置函数地址: %p\n", c.Context()) // 输出类似: 0x1040a1390 clientdata := c.Context().(*entity.ClientData) + clientdata.SetCrossDomain(true) player := entity.NewPlayer( entity.WithUserID(userid), //注入ID entity.WithConn(c), //注入conn ) core.Mainplayer.Store(userid, player) - clientdata.Player = player + clientdata.SetPlayer(player) //= player + //clientdata.UserID = userid + //c.SetContext(clientdata) + // c.SetContext("ahahha") return player // return nil } diff --git a/modules/blazing/service/login.go b/modules/blazing/service/login.go index 56431c684..8e5a8e68e 100644 --- a/modules/blazing/service/login.go +++ b/modules/blazing/service/login.go @@ -50,7 +50,13 @@ func (s *LoginService) GetSessionId(accountID uint) (string, string, error) { // /t1. // 以上过程只需全局一次,且应在生成ID之前完成。 } -func (s *LoginService) SetServerID(OnlineID uint32, Port uint16) error { +func (s *LoginService) SetServerID(OnlineID uint32, Port uint16, t *struct { + Kick func(int32) error + + RegisterLogic func(int32) error + UserLogin func(int32, int32) error + UserLogout func(int32, int32) error +}) error { m := cool.DBM(s.Model).Where("online_id", OnlineID) @@ -65,7 +71,9 @@ func (s *LoginService) SetServerID(OnlineID uint32, Port uint16) error { return err } - + var tttt model.ServerList + record.Struct(&tttt) + //t.Quit(int32(tttt.Port)) _, err = m.Data(&model.ServerList{OnlineID: OnlineID, Port: Port}).Where("online_id", OnlineID).Update() return nil