service.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package service
  2. import (
  3. "errors"
  4. "reflect"
  5. "strings"
  6. "git.bvbej.com/bvbej/base-golang/pkg/websocket/peer"
  7. )
  8. type Handler struct {
  9. Receiver reflect.Value // 值
  10. Method reflect.Method // 方法
  11. Type reflect.Type // 类型
  12. IsRawArg bool // 数据是否需要序列化
  13. }
  14. type Service struct {
  15. Name string // 服务名
  16. Type reflect.Type // 服务类型
  17. Receiver reflect.Value // 服务值
  18. Handlers map[string]*Handler // 注册的方法列表
  19. component Component
  20. }
  21. func NewService(comp Component) *Service {
  22. s := &Service{
  23. Type: reflect.TypeOf(comp),
  24. Receiver: reflect.ValueOf(comp),
  25. component: comp,
  26. }
  27. s.Name = strings.ToLower(reflect.Indirect(s.Receiver).Type().Name())
  28. //调用初始化方法
  29. s.component.Init()
  30. return s
  31. }
  32. // 遍历取出满足条件的函数
  33. func (s *Service) suitableHandlerMethods(typ reflect.Type) map[string]*Handler {
  34. methods := make(map[string]*Handler)
  35. for m := 0; m < typ.NumMethod(); m++ {
  36. method := typ.Method(m)
  37. mt := method.Type
  38. mn := method.Name
  39. if isHandlerMethod(method) {
  40. raw := false
  41. if mt.In(2) == typeOfBytes {
  42. raw = true
  43. }
  44. mn = strings.ToLower(mn)
  45. methods[mn] = &Handler{Method: method, Type: mt.In(2), IsRawArg: raw}
  46. }
  47. }
  48. return methods
  49. }
  50. // 取结构体中的函数
  51. func (s *Service) ExtractHandler() error {
  52. typeName := reflect.Indirect(s.Receiver).Type().Name()
  53. if typeName == "" {
  54. return errors.New("no service name for type " + s.Type.String())
  55. }
  56. if !isExported(typeName) {
  57. return errors.New("type " + typeName + " is not exported")
  58. }
  59. s.Handlers = s.suitableHandlerMethods(s.Type)
  60. for i := range s.Handlers {
  61. s.Handlers[i].Receiver = s.Receiver
  62. }
  63. if reflect.Indirect(s.Receiver).NumField() > 0 {
  64. filedNum := reflect.Indirect(s.Receiver).NumField()
  65. for i := 0; i < filedNum; i++ {
  66. ty := reflect.Indirect(s.Receiver).Field(i).Type().Name()
  67. if ty == ChildName {
  68. h := s.suitableHandlerMethods(reflect.Indirect(s.Receiver).Field(i).Elem().Type())
  69. for ih, v := range h {
  70. s.Handlers[ih] = v
  71. s.Handlers[ih].Receiver = reflect.Indirect(s.Receiver).Field(i).Elem()
  72. }
  73. }
  74. }
  75. }
  76. if len(s.Handlers) == 0 {
  77. str := "service: "
  78. method := s.suitableHandlerMethods(reflect.PtrTo(s.Type))
  79. if len(method) != 0 {
  80. str = "type " + s.Name + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
  81. } else {
  82. str = "type " + s.Name + " has no exported methods of suitable type"
  83. }
  84. return errors.New(str)
  85. }
  86. return nil
  87. }
  88. func (s *Service) OnSessionClose(session *peer.Session) bool {
  89. return s.component.OnSessionClose(session)
  90. }