package modules import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/pb" "reflect" "strings" "unicode" "unicode/utf8" "go_dreamfactory/lego/base" "go_dreamfactory/lego/core" "go_dreamfactory/lego/core/cbase" ) /* 模块网关组件的基类实现 模块接收用户的消息请求都需要通过装备继承此组件的api组件来实现 */ // var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem() var typeOfSession = reflect.TypeOf((*comm.IUserSession)(nil)).Elem() var typeOfMapStringIntface = reflect.TypeOf((map[string]interface{})(nil)).Elem() var typeOfCode = reflect.TypeOf((*comm.ErrorCode)(nil)).Elem() var typeOfErrorCode = reflect.TypeOf((*pb.ErrorCode)(nil)).Elem() var typeOfError = reflect.TypeOf((*error)(nil)).Elem() /* 模块 网关组件 接收处理用户传递消息 */ type MCompGate struct { cbase.ModuleCompBase service base.IRPCXService //rpc服务对象 module core.IModule //当前业务模块 comp core.IModuleComp //网关组件自己 scomp comm.ISC_GateRouteComp } //组件初始化接口 func (this *MCompGate) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, options) this.service = service.(base.IRPCXService) this.module = module this.comp = comp return } //组件启动接口,启动时将自己接收用户消息的处理函数注册到services/comp_gateroute.go 对象中 func (this *MCompGate) Start() (err error) { if err = this.ModuleCompBase.Start(); err != nil { return } var comp core.IServiceComp //注册远程路由 if comp, err = this.service.GetComp(comm.SC_ServiceGateRouteComp); err != nil { return } this.scomp = comp.(comm.ISC_GateRouteComp) this.suitableMethods(reflect.TypeOf(this.comp)) return } //反射注册相关接口道services/comp_gateroute.go 对象中 func (this *MCompGate) suitableMethods(typ reflect.Type) { for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) this.reflectionRouteHandle(method) this.reflectionRouteCheck(method) } } //反射注册路由处理函数 func (this *MCompGate) reflectionRouteHandle(method reflect.Method) { mtype := method.Type mname := method.Name if method.PkgPath != "" { return } if mtype.NumIn() != 4 { return } ctxType := mtype.In(1) if !ctxType.Implements(typeOfSession) { return } argType := mtype.In(2) if !argType.Implements(typeOfMapStringIntface) { return } replyType := mtype.In(3) if replyType.Kind() != reflect.Ptr { return } if !this.isExportedOrBuiltinType(replyType) { return } if mtype.NumOut() != 1 { return } returnCodeType := mtype.Out(0) if returnCodeType != typeOfErrorCode { return } this.scomp.RegisterRoute(fmt.Sprintf("%s.%s", this.module.GetType(), strings.ToLower(mname)), reflect.ValueOf(this.comp), replyType, method) } //反射注册路由校验函数 func (this *MCompGate) reflectionRouteCheck(method reflect.Method) { mtype := method.Type mname := strings.Split(method.Name, "_") if len(mname) != 2 || mname[1] != "Check" { return } if method.PkgPath != "" { return } if mtype.NumIn() != 3 { return } ctxType := mtype.In(1) if !ctxType.Implements(typeOfSession) { return } replyType := mtype.In(2) if replyType.Kind() != reflect.Ptr { return } if !this.isExportedOrBuiltinType(replyType) { return } if mtype.NumOut() != 2 { return } returnMapType := mtype.Out(0) if !returnMapType.Implements(typeOfMapStringIntface) { return } returnCodeType := mtype.Out(1) if returnCodeType != typeOfCode { return } this.scomp.RegisterRouteCheck(fmt.Sprintf("%s.%s", this.module.GetType(), strings.ToLower(mname[0])), reflect.ValueOf(this.comp), replyType, method) } func (this *MCompGate) isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } return this.isExported(t.Name()) || t.PkgPath() == "" } func (this *MCompGate) isExported(name string) bool { rune, _ := utf8.DecodeRuneInString(name) return unicode.IsUpper(rune) }