package m_comps import ( "context" "reflect" "unicode" "unicode/utf8" "github.com/liwei1dao/lego/base" "github.com/liwei1dao/lego/core" "github.com/liwei1dao/lego/core/cbase" "github.com/liwei1dao/lego/sys/log" ) var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem() var typeOfError = reflect.TypeOf((*error)(nil)).Elem() /* 模块 网关组件 接收处理用户传递消息 */ type MComp_GateComp struct { cbase.ModuleCompBase service base.IRPCXService } 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.service = service.(base.IRPCXService) this.suitableMethods(reflect.TypeOf(comp)) return } // func (this *MComp_GateComp) Start() (err error) { // if err = this.ModuleCompBase.Start(); err != nil { // return // } // isRegisterLocalRoute := false // //注册本地路由 // //注册远程路由 // cc, e := this.service.GetComp(comm.SC_ServiceGateRouteComp) // if e == nil { // cc.(comm.ISC_GateRouteComp).RegisterRoute(this.ComId, this.comp.ReceiveMsg) // isRegisterLocalRoute = true // } // if !isRegisterLocalRoute { // return fmt.Errorf("MC_GateComp 未成功注册路由!") // } // return // } func (this *MComp_GateComp) suitableMethods(typ reflect.Type) { for m := 0; m < typ.NumMethod(); m++ { method := typ.Method(m) mtype := method.Type mname := method.Name // Method must be exported. if method.PkgPath != "" { continue } // Method needs four ins: receiver, context.Context, *args, *reply. if mtype.NumIn() != 4 { continue } // First arg must be context.Context ctxType := mtype.In(1) if !ctxType.Implements(typeOfContext) { continue } // Second arg need not be a pointer. argType := mtype.In(2) if !this.isExportedOrBuiltinType(argType) { continue } // Third arg must be a pointer. replyType := mtype.In(3) if replyType.Kind() != reflect.Ptr { continue } // Reply type must be exported. if !this.isExportedOrBuiltinType(replyType) { continue } // Method needs one out. if mtype.NumOut() != 1 { continue } // The return type of the method must be error. if returnType := mtype.Out(0); returnType != typeOfError { continue } log.Debugf("RegisterFunctionName:%s", mname) this.service.RegisterFunctionName(mname, method) } } func (this *MComp_GateComp) isExportedOrBuiltinType(t reflect.Type) bool { for t.Kind() == reflect.Ptr { t = t.Elem() } // PkgPath will be non-empty even for an exported type, // so we need to check the type name as well. return this.isExported(t.Name()) || t.PkgPath() == "" } func (this *MComp_GateComp) isExported(name string) bool { rune, _ := utf8.DecodeRuneInString(name) return unicode.IsUpper(rune) }