refactor(logic): 重构逻辑模块
- 移除了 player.go 中的 SendPackBytes 方法 - 将 TomeeHeader 中的 CMDID 改为 CMD,类型从 uint32 改为 EnumCommandID - 删除了 controller 文件夹下的 service.go 和 login.go - 新增了 login 文件夹下的 PlayerLoginService.go - 优化了 main.go 中的 Start 函数,使用 controller.Recv 作为回调
This commit is contained in:
186
logic/main.go
186
logic/main.go
@@ -1,208 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
"github.com/lunixbochs/struc"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
|
||||
"blazing/common/core/info"
|
||||
"blazing/common/data/entity"
|
||||
"blazing/common/socket"
|
||||
"blazing/common/socket/cmd"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/cool"
|
||||
"blazing/logic/controller"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
var (
|
||||
maininfocodec = info.NewInfoCodec() //创建一个InfoCodec实例
|
||||
maincontroller = controller.NewController() //注入service
|
||||
mainplayer sync.Map //玩家数据
|
||||
maincmdcache sync.Map //命令缓存
|
||||
)
|
||||
|
||||
func main() {
|
||||
if cool.IsRedisMode {
|
||||
go cool.ListenFunc(gctx.New())
|
||||
}
|
||||
|
||||
Start(cool.Config.PortBL) //注入service
|
||||
}
|
||||
func Start(port string) {
|
||||
|
||||
head := handler.NewTomeeHandler()
|
||||
head.Callback = recv
|
||||
head.Callback = controller.Recv
|
||||
socket.NewServer(socket.WithPort(port), socket.WithSocketHandler(head)).Start()
|
||||
}
|
||||
func recv(c gnet.Conn, data handler.TomeeHeader) {
|
||||
// 处理接收到的TomeeHeader数据
|
||||
// fmt.Println("收到数据:", data)
|
||||
processWithReflection(c, data)
|
||||
|
||||
}
|
||||
|
||||
func getplayer(c gnet.Conn, userid uint32) *entity.Player { //TODO 这里待优化,可能存在内存泄漏问题
|
||||
|
||||
clientdata := c.Context().(*entity.ClientData)
|
||||
if clientdata != nil && clientdata.Player != nil {
|
||||
return clientdata.Player
|
||||
}
|
||||
var player *entity.Player
|
||||
if player1, ok := mainplayer.Load((userid)); !ok {
|
||||
player = entity.NewPlayer(
|
||||
entity.WithUserID(userid), //注入ID
|
||||
entity.WithConn(c), //注入conn
|
||||
)
|
||||
mainplayer.Store(userid, player)
|
||||
} else {
|
||||
player = player1.(*entity.Player) //取成功,否则创建
|
||||
}
|
||||
clientdata.Player = player
|
||||
return player
|
||||
}
|
||||
|
||||
// 遍历结构体方法并执行RECV_cmd
|
||||
func processWithReflection(c gnet.Conn, pp handler.TomeeHeader) {
|
||||
data := pp.Data
|
||||
player := getplayer(c, pp.UserID) //获取player实例
|
||||
cmdlister, ok := maincmdcache.Load(pp.CMDID) //TODO 待实现对不同用户初始化方法以取消全局cmdcache
|
||||
|
||||
if ok {
|
||||
|
||||
callhandler(cmdlister.(reflect.Value), data, player, cmd.EnumCommandID(pp.CMDID))
|
||||
|
||||
// return
|
||||
} else {
|
||||
// 获取对象的反射值和类型
|
||||
value := reflect.ValueOf(maincontroller)
|
||||
|
||||
// 如果传入的是指针,获取其指向的值
|
||||
if value.Kind() == reflect.Ptr {
|
||||
if value.IsNil() {
|
||||
fmt.Println("错误: 传入的是nil指针")
|
||||
return
|
||||
}
|
||||
value = value.Elem()
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
typ := value.Type()
|
||||
|
||||
// 遍历所有方法
|
||||
fmt.Printf("检查结构体 %s 的方法...\n", typ.Name(), typ.NumMethod())
|
||||
for i := 0; i < typ.NumMethod(); i++ {
|
||||
method := typ.Method(i)
|
||||
|
||||
if method.Type.NumIn() == 4 { //&& // TODO 接收者 + 2个参数 一个是类型,一个是player
|
||||
//method.Type.In(1) == reflect.TypeOf([]byte{}
|
||||
|
||||
// 获取方法值
|
||||
methodValue := value.MethodByName(method.Name)
|
||||
|
||||
// 准备参数
|
||||
cmd1 := method.Name[len("Recv_"):len(method.Name)]
|
||||
cmdint, _ := strconv.Atoi(cmd1)
|
||||
if cmdint == int(pp.CMDID) {
|
||||
if !cmd.Isexist(cmd.CommandID, cmd.EnumCommandID(pp.CMDID)) {
|
||||
fmt.Println("ID方法存在cmd未注册", pp.CMDID, cmd.CommandID)
|
||||
}
|
||||
maincmdcache.Store(pp.CMDID, methodValue) //TODO 待实现对不同用户初始化方法以取消全局cmdcache
|
||||
callhandler(methodValue, data, player, cmd.EnumCommandID(pp.CMDID))
|
||||
|
||||
}
|
||||
|
||||
//return
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func callhandler(cmdlister reflect.Value, data []byte, player *entity.Player, cmd cmd.EnumCommandID) {
|
||||
//TODO 待实现返回参数返回客户端???实现直接返回对象进行序列化 传递chan待返回
|
||||
//TODO 已实现,待测试结构体序列化
|
||||
recvchan := make(chan any, 1) //传递自定义chan
|
||||
|
||||
go func() { //TODO 待实现ants线程池,以及确认是否存在顺序混乱问题https://github.com/lxzan/gws/issues/3
|
||||
retv := <-recvchan
|
||||
|
||||
switch ttt := retv.(type) {
|
||||
case []byte:
|
||||
player.SendPackBytes(cmd, ttt)
|
||||
|
||||
default:
|
||||
var data1 bytes.Buffer
|
||||
struc.Unpack(&data1, &ttt)
|
||||
player.SendPackBytes(cmd, data1.Bytes())
|
||||
|
||||
}
|
||||
}()
|
||||
cmdlister.Call([]reflect.Value{
|
||||
reflect.ValueOf(data),
|
||||
reflect.ValueOf(player),
|
||||
reflect.ValueOf(recvchan),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func getincodec(cmdid cmd.EnumCommandID, data []byte) reflect.Value {
|
||||
// 获取对象的反射值和类型
|
||||
value := reflect.ValueOf(maininfocodec)
|
||||
|
||||
// 如果传入的是指针,获取其指向的值
|
||||
if value.Kind() == reflect.Ptr {
|
||||
if value.IsNil() {
|
||||
fmt.Println("错误: 传入的是nil指针")
|
||||
return reflect.ValueOf(nil)
|
||||
}
|
||||
value = value.Elem()
|
||||
}
|
||||
|
||||
// 获取类型
|
||||
typ := value.Type()
|
||||
|
||||
// 遍历所有方法
|
||||
fmt.Printf("检查结构体 %s 的方法...\n", typ.Name(), typ.NumMethod())
|
||||
for i := 0; i < typ.NumMethod(); i++ {
|
||||
method := typ.Method(i)
|
||||
|
||||
if method.Type.NumIn() == 2 && // 接收者 + 2个参数
|
||||
method.Type.In(1) == reflect.TypeOf([]byte{}) {
|
||||
|
||||
// 获取方法值
|
||||
methodValue := value.MethodByName(method.Name)
|
||||
|
||||
// 准备参数
|
||||
cmd1 := method.Name[len("In_"):len(method.Name)]
|
||||
cmdint, _ := strconv.Atoi(cmd1)
|
||||
if cmdint == int(cmdid) {
|
||||
if !cmd.Isexist(cmd.CommandID, cmd.EnumCommandID(cmdid)) {
|
||||
fmt.Println("ID方法存在cmd未注册", cmdid, cmd.CommandID)
|
||||
}
|
||||
|
||||
//data := pp.Data
|
||||
|
||||
// 调用方法
|
||||
tt := methodValue.Call([]reflect.Value{
|
||||
// reflect.ValueOf(cmdint),
|
||||
reflect.ValueOf(data),
|
||||
})
|
||||
|
||||
return tt[0]
|
||||
}
|
||||
|
||||
//return
|
||||
}
|
||||
//}
|
||||
}
|
||||
return reflect.ValueOf(nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user