1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- package service
- import (
- "errors"
- "git.bvbej.com/bvbej/base-golang/pkg/websocket/util"
- "reflect"
- "strings"
- "git.bvbej.com/bvbej/base-golang/pkg/websocket/peer"
- )
- 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)
- }
|