package processor import ( "fmt" "github.com/golang/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "reflect" ) type RegisterMetas map[protoreflect.Enum]struct { Typ any // 请求结构体,注意不能使用指针 Delegate any // 处理方法 } func NewProcessor() *Processor { return &Processor{ types: make(map[int32]reflect.Type), delegates: make(map[int32]reflect.Value), } } type Processor struct { types map[int32]reflect.Type delegates map[int32]reflect.Value } func (h *Processor) RegisterMessages(metas RegisterMetas) { for cmd, meta := range metas { h.RegisterMessage(int32(cmd.Number()), meta.Typ, meta.Delegate) } } func (h *Processor) RegisterMessage(cmd int32, msg, delegate any) { h.types[cmd] = reflect.TypeOf(msg) h.delegates[cmd] = reflect.ValueOf(delegate) } func (h *Processor) UnregisterMessage(cmd int32) { delete(h.types, cmd) } func (h *Processor) GetMessageType(cmd int32) reflect.Type { return h.types[cmd] } func (h *Processor) Unmarshal(cmd int32, data []byte) (any, error) { typ := h.GetMessageType(cmd) if typ == nil { return nil, fmt.Errorf("invalid cmd: %d", cmd) } v := reflect.New(typ).Interface() if data == nil { return v, nil } if err := proto.Unmarshal(data, v.(proto.Message)); err != nil { return nil, err } return v, nil } func (h *Processor) Dispatch(cmd int32, params ...any) error { in := make([]reflect.Value, len(params)) for i, param := range params { in[i] = reflect.ValueOf(param) } delegate, ok := h.delegates[cmd] if !ok { return fmt.Errorf("cmd %d delegates not found", cmd) } delegate.Call(in) return nil }