2024-07-23 10:23:43 +08:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2024-07-31 16:49:14 +08:00
|
|
|
"gitea.bvbej.com/bvbej/base-golang/pkg/websocket/util"
|
2024-07-23 10:23:43 +08:00
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
|
2024-07-31 16:49:14 +08:00
|
|
|
"gitea.bvbej.com/bvbej/base-golang/pkg/websocket/peer"
|
2024-07-23 10:23:43 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type Handler struct {
|
|
|
|
Receiver reflect.Value // 值
|
|
|
|
Method reflect.Method // 方法
|
|
|
|
Type reflect.Type // 类型
|
|
|
|
IsRawArg bool // 数据是否需要序列化
|
|
|
|
}
|
|
|
|
|
|
|
|
type Service struct {
|
|
|
|
Name string // 服务名
|
|
|
|
Type reflect.Type // 服务类型
|
|
|
|
Receiver reflect.Value // 服务值
|
|
|
|
Handlers map[string]*Handler // 注册的方法列表
|
|
|
|
Component Component
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewService(comp Component) *Service {
|
|
|
|
s := &Service{
|
|
|
|
Type: reflect.TypeOf(comp),
|
|
|
|
Receiver: reflect.ValueOf(comp),
|
|
|
|
Component: comp,
|
|
|
|
}
|
|
|
|
s.Name = strings.ToLower(reflect.Indirect(s.Receiver).Type().Name())
|
|
|
|
//调用初始化方法
|
|
|
|
s.Component.Init()
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) SuitableHandlerMethods(typ reflect.Type) map[string]*Handler {
|
|
|
|
methods := make(map[string]*Handler)
|
|
|
|
for m := 0; m < typ.NumMethod(); m++ {
|
|
|
|
method := typ.Method(m)
|
|
|
|
mt := method.Type
|
|
|
|
mn := method.Name
|
|
|
|
if isHandlerMethod(method) {
|
|
|
|
raw := false
|
|
|
|
if mt.In(2) == typeOfBytes {
|
|
|
|
raw = true
|
|
|
|
}
|
|
|
|
mn = strings.ToLower(mn)
|
|
|
|
methods[mn] = &Handler{Method: method, Type: mt.In(2), IsRawArg: raw}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return methods
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) ExtractHandler() error {
|
|
|
|
typeName := reflect.Indirect(s.Receiver).Type().Name()
|
|
|
|
if typeName == "" {
|
|
|
|
return errors.New("no service name for type " + s.Type.String())
|
|
|
|
}
|
|
|
|
if !util.IsExported(typeName) {
|
|
|
|
return errors.New("type " + typeName + " is not exported")
|
|
|
|
}
|
|
|
|
s.Handlers = s.SuitableHandlerMethods(s.Type)
|
|
|
|
for i := range s.Handlers {
|
|
|
|
s.Handlers[i].Receiver = s.Receiver
|
|
|
|
}
|
|
|
|
if reflect.Indirect(s.Receiver).NumField() > 0 {
|
|
|
|
filedNum := reflect.Indirect(s.Receiver).NumField()
|
|
|
|
for i := 0; i < filedNum; i++ {
|
|
|
|
ty := reflect.Indirect(s.Receiver).Field(i).Type().Name()
|
|
|
|
if ty == ChildName {
|
|
|
|
h := s.SuitableHandlerMethods(reflect.Indirect(s.Receiver).Field(i).Elem().Type())
|
|
|
|
for ih, v := range h {
|
|
|
|
s.Handlers[ih] = v
|
|
|
|
s.Handlers[ih].Receiver = reflect.Indirect(s.Receiver).Field(i).Elem()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(s.Handlers) == 0 {
|
|
|
|
str := "service: "
|
|
|
|
method := s.SuitableHandlerMethods(reflect.PtrTo(s.Type))
|
|
|
|
if len(method) != 0 {
|
|
|
|
str = "type " + s.Name + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
|
|
|
|
} else {
|
|
|
|
str = "type " + s.Name + " has no exported methods of suitable type"
|
|
|
|
}
|
|
|
|
return errors.New(str)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) OnSessionClose(session *peer.Session) bool {
|
|
|
|
return s.Component.OnSessionClose(session)
|
|
|
|
}
|