package modules import ( "context" "fmt" "go_dreamfactory/comm" "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 typeOfError = reflect.TypeOf((*error)(nil)).Elem() /* 模块 网关组件 接收处理用户传递消息 */ type MComp_GateComp struct { cbase.ModuleCompBase S base.IRPCXService //rpc服务对象 M IModule //当前业务模块 comp core.IModuleComp //网关组件自己 scomp comm.ISC_GateRouteComp } //组件初始化接口 func (this *MComp_GateComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.ModuleCompBase.Init(service, module, comp, options) this.S = service.(base.IRPCXService) this.M = module.(IModule) this.comp = comp return } //组件启动接口,启动时将自己接收用户消息的处理函数注册到services/comp_gateroute.go 对象中 func (this *MComp_GateComp) Start() (err error) { if err = this.ModuleCompBase.Start(); err != nil { return } var comp core.IServiceComp //注册远程路由 if comp, err = this.S.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 *MComp_GateComp) suitableMethods(typ reflect.Type) { for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) this.reflectionRouteHandle(method) } } //反射路由处理函数 func (this *MComp_GateComp) reflectionRouteHandle(method reflect.Method) bool { mtype := method.Type mname := method.Name if method.PkgPath != "" { return false } if mtype.NumIn() != 4 { return false } ctxType := mtype.In(1) if !ctxType.Implements(typeOfContext) { return false } argType := mtype.In(2) if !argType.Implements(typeOfSession) { return false } replyType := mtype.In(3) if replyType.Kind() != reflect.Ptr { return false } if !this.isExportedOrBuiltinType(replyType) { return false } if mtype.NumOut() != 1 { return false } if returnType := mtype.Out(0); returnType != typeOfError { return false } this.scomp.RegisterRoute(fmt.Sprintf("%s.%s", this.M.GetType(), strings.ToLower(mname)), reflect.ValueOf(this.comp), replyType, method) return true } func (this *MComp_GateComp) isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } return this.isExported(t.Name()) || t.PkgPath() == "" } func (this *MComp_GateComp) isExported(name string) bool { rune, _ := utf8.DecodeRuneInString(name) return unicode.IsUpper(rune) }