go_dreamfactory/modules/m_comps/gate_comp.go
2022-05-31 16:35:44 +08:00

104 lines
2.6 KiB
Go

package m_comps
import (
"context"
"go_dreamfactory/comm"
"reflect"
"unicode"
"unicode/utf8"
"github.com/liwei1dao/lego/base"
"github.com/liwei1dao/lego/core"
"github.com/liwei1dao/lego/core/cbase"
)
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
service base.IRPCXService
comp core.IModuleComp
}
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.comp = comp
return
}
func (this *MComp_GateComp) 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.suitableMethods(comp.(comm.ISC_GateRouteComp), reflect.TypeOf(this.comp))
return
}
func (this *MComp_GateComp) suitableMethods(scomp comm.ISC_GateRouteComp, 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 !argType.Implements(typeOfSession) {
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
}
scomp.RegisterRoute(mname, reflect.ValueOf(this.comp), replyType, method)
}
}
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)
}