-
Notifications
You must be signed in to change notification settings - Fork 0
/
mock_client_handler.go
99 lines (94 loc) · 3.23 KB
/
mock_client_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package testclient
import (
"fmt"
. "github.com/fish-tennis/gnet"
"github.com/fish-tennis/gtestclient/logger"
"github.com/fish-tennis/gtestclient/pb"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"reflect"
"strings"
"time"
)
type MockClientHandler struct {
DefaultConnectionHandler
methods map[PacketCommand]reflect.Method
}
func NewMockClientHandler(protoCodec Codec) *MockClientHandler {
handler := &MockClientHandler{
DefaultConnectionHandler: *NewDefaultConnectionHandler(protoCodec),
methods: make(map[PacketCommand]reflect.Method),
}
handler.RegisterHeartBeat(func() Packet {
return NewProtoPacket(PacketCommand(pb.CmdInner_Cmd_HeartBeatReq), &pb.HeartBeatReq{
Timestamp: uint64(time.Now().UnixNano() / int64(time.Millisecond)),
})
})
handler.Register(PacketCommand(pb.CmdInner_Cmd_HeartBeatRes), func(connection Connection, packet Packet) {
}, new(pb.HeartBeatRes))
handler.SetUnRegisterHandler(func(connection Connection, packet Packet) {
logger.Debug("un register %v", string(packet.Message().ProtoReflect().Descriptor().Name()))
})
return handler
}
func (this *MockClientHandler) OnRecvPacket(connection Connection, packet Packet) {
if connection.GetTag() != nil {
accountName := connection.GetTag().(string)
mockClient := _testClient.getMockClientByAccountName(accountName)
if mockClient == nil {
return
}
if protoPacket, ok := packet.(*ProtoPacket); ok {
handlerMethod, ok2 := this.methods[protoPacket.Command()]
if ok2 {
handlerMethod.Func.Call([]reflect.Value{reflect.ValueOf(mockClient), reflect.ValueOf(protoPacket.Message())})
return
}
}
this.DefaultConnectionHandler.OnRecvPacket(connection, packet)
}
}
// 通过反射自动注册消息回调
func (this *MockClientHandler) autoRegister() {
typ := reflect.TypeOf(&MockClient{})
for i := 0; i < typ.NumMethod(); i++ {
method := typ.Method(i)
// func (this *MockClient) OnMessageName(res *pb.MessageName)
if method.Type.NumIn() != 2 || !strings.HasPrefix(method.Name, "On") {
continue
}
methonArg1 := method.Type.In(1)
if !strings.HasPrefix(methonArg1.String(), "*pb.") {
continue
}
// 消息名,如: LoginRes
messageName := methonArg1.String()[strings.LastIndex(methonArg1.String(), ".")+1:]
// 函数名必须是onLoginRes
if method.Name != fmt.Sprintf("On%v", messageName) {
logger.Debug("methodName not match:%v", method.Name)
continue
}
// Cmd_LoginRes
enumValueName := fmt.Sprintf("Cmd_%v", messageName)
var messageId int32
protoregistry.GlobalTypes.RangeEnums(func(enumType protoreflect.EnumType) bool {
// gserver.Login.CmdLogin
enumValueDescriptor := enumType.Descriptor().Values().ByName(protoreflect.Name(enumValueName))
if enumValueDescriptor != nil {
messageId = int32(enumValueDescriptor.Number())
return false
}
return true
})
if messageId == 0 {
continue
}
cmd := PacketCommand(messageId)
// 注册消息回调到组件上
this.methods[cmd] = method
// 注册消息的构造函数
this.DefaultConnectionHandler.Register(cmd, nil, reflect.New(methonArg1.Elem()).Interface().(proto.Message))
logger.Debug("register %v %v", messageId, method.Name)
}
}