service.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. func (s *Service) ExtractHandler() error {
  51. typeName := reflect.Indirect(s.Receiver).Type().Name()
  52. if typeName == "" {
  53. return errors.New("no service name for type " + s.Type.String())
  54. }
  55. if !isExported(typeName) {
  56. return errors.New("type " + typeName + " is not exported")
  57. }
  58. s.Handlers = s.suitableHandlerMethods(s.Type)
  59. for i := range s.Handlers {
  60. s.Handlers[i].Receiver = s.Receiver
  61. }
  62. if reflect.Indirect(s.Receiver).NumField() > 0 {
  63. filedNum := reflect.Indirect(s.Receiver).NumField()
  64. for i := 0; i < filedNum; i++ {
  65. ty := reflect.Indirect(s.Receiver).Field(i).Type().Name()
  66. if ty == ChildName {
  67. h := s.suitableHandlerMethods(reflect.Indirect(s.Receiver).Field(i).Elem().Type())
  68. for ih, v := range h {
  69. s.Handlers[ih] = v
  70. s.Handlers[ih].Receiver = reflect.Indirect(s.Receiver).Field(i).Elem()
  71. }
  72. }
  73. }
  74. }
  75. if len(s.Handlers) == 0 {
  76. str := "service: "
  77. method := s.suitableHandlerMethods(reflect.PtrTo(s.Type))
  78. if len(method) != 0 {
  79. str = "type " + s.Name + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
  80. } else {
  81. str = "type " + s.Name + " has no exported methods of suitable type"
  82. }
  83. return errors.New(str)
  84. }
  85. return nil
  86. }
  87. func (s *Service) OnSessionClose(session *peer.Session) bool {
  88. return s.component.OnSessionClose(session)
  89. }