You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.3 KiB
145 lines
4.3 KiB
package modules
|
|
|
|
import (
|
|
"context"
|
|
"yunyan/comm"
|
|
"fmt"
|
|
"log"
|
|
"reflect"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
|
|
"yunyan/lego/base"
|
|
"yunyan/lego/core"
|
|
"yunyan/lego/core/cbase"
|
|
)
|
|
|
|
/*
|
|
模块网关组件的基类实现 模块接收用户的消息请求都需要通过装备继承此组件的api组件来实现
|
|
*/
|
|
|
|
// var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem()
|
|
var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem()
|
|
|
|
/*
|
|
模块 网关组件 接收处理用户传递消息
|
|
*/
|
|
type MCompHttpGate struct {
|
|
cbase.ModuleCompBase
|
|
service base.IRPCXService //rpc服务对象
|
|
module core.IModule //当前业务模块
|
|
comp core.IModuleComp //网关组件自己
|
|
scomp comm.ISC_HttpRouteComp
|
|
Version string //版本标识
|
|
EncryptMsgs []string //加密协议
|
|
}
|
|
|
|
// 组件初始化接口
|
|
func (this *MCompHttpGate) 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 *MCompHttpGate) Start() (err error) {
|
|
if err = this.ModuleCompBase.Start(); err != nil {
|
|
return
|
|
}
|
|
var comp core.IServiceComp
|
|
//注册远程路由
|
|
if comp, err = this.service.GetComp(comm.SC_ServiceHttpRouteComp); err != nil {
|
|
return
|
|
}
|
|
this.scomp = comp.(comm.ISC_HttpRouteComp)
|
|
this.suitableMethods()
|
|
return
|
|
}
|
|
|
|
// 反射注册相关接口道services/comp_gateroute.go 对象中
|
|
func (this *MCompHttpGate) suitableMethods() {
|
|
typ := reflect.TypeOf(this.comp)
|
|
for m := 0; m < typ.NumMethod(); m++ {
|
|
method := typ.Method(m)
|
|
mname := method.Name
|
|
if mname == "Start" ||
|
|
mname == "Init" ||
|
|
mname == "Destroy" ||
|
|
strings.HasSuffix(mname, "Check") {
|
|
continue
|
|
}
|
|
this.reflectionRouteHandle(typ, method)
|
|
}
|
|
}
|
|
|
|
// 反射注册路由处理函数
|
|
func (this *MCompHttpGate) reflectionRouteHandle(typ reflect.Type, method reflect.Method) (ret bool) {
|
|
mtype := method.Type
|
|
mname := method.Name
|
|
isEncrypt := false
|
|
if method.PkgPath != "" {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
if mtype.NumIn() != 3 {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
contextType := mtype.In(1)
|
|
if !contextType.Implements(typeOfSession) {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
agrType := mtype.In(2)
|
|
if !agrType.Implements(typeOfMessage) {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
if mtype.NumOut() != 2 {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
returnDataType := mtype.Out(0)
|
|
if !returnDataType.Implements(typeOfMessage) && returnDataType != typeOfByteSlice {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
|
|
returnErrDataType := mtype.Out(1)
|
|
if returnErrDataType != typeOfErrorData {
|
|
log.Panicf("反射注册用户处理函数错误 [%s-%s] Api接口格式错误", this.module.GetType(), mname)
|
|
return
|
|
}
|
|
|
|
if this.EncryptMsgs != nil && len(this.EncryptMsgs) > 0 {
|
|
for _, v := range this.EncryptMsgs {
|
|
if v == mname {
|
|
isEncrypt = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
//注册路由函数
|
|
if this.Version == "" {
|
|
this.scomp.RegisterRoute(fmt.Sprintf("%s_%s", this.module.GetType(), strings.ToLower(mname)), isEncrypt, reflect.ValueOf(this.comp), agrType, method)
|
|
} else {
|
|
this.scomp.RegisterRoute(fmt.Sprintf("%s_%s_%s", this.module.GetType(), strings.ToLower(mname), this.Version), isEncrypt, reflect.ValueOf(this.comp), agrType, method)
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (this *MCompHttpGate) isExportedOrBuiltinType(t reflect.Type) bool {
|
|
for t.Kind() == reflect.Ptr {
|
|
t = t.Elem()
|
|
}
|
|
return this.isExported(t.Name()) || t.PkgPath() == ""
|
|
}
|
|
|
|
func (this *MCompHttpGate) isExported(name string) bool {
|
|
rune, _ := utf8.DecodeRuneInString(name)
|
|
return unicode.IsUpper(rune)
|
|
}
|
|
|