mirror of
https://github.com/smallnest/rpcx.git
synced 2025-10-06 00:26:58 +08:00
add reflection so that you can use it to get definition of services
This commit is contained in:
3
go.mod
3
go.mod
@@ -3,6 +3,7 @@ module github.com/smallnest/rpcx
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/ChimeraCoder/gojson v1.1.0
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20191122014323-8cc8f217b23a // indirect
|
||||
github.com/anacrolix/envpprof v1.0.1 // indirect
|
||||
@@ -27,11 +28,13 @@ require (
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e
|
||||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
|
||||
github.com/json-iterator/go v1.1.9
|
||||
github.com/juju/ratelimit v1.0.1
|
||||
github.com/julienschmidt/httprouter v1.2.0
|
||||
github.com/kavu/go_reuseport v1.4.0
|
||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||
github.com/klauspost/reedsolomon v1.9.2 // indirect
|
||||
github.com/kr/pretty v0.1.0
|
||||
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect
|
||||
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f // indirect
|
||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect
|
||||
|
21
go.sum
21
go.sum
@@ -1,11 +1,12 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ChimeraCoder/gojson v1.1.0 h1:/6S8djl/jColpJGTYniA3xrqJWuKeyEozzPtpr5L4Pw=
|
||||
github.com/ChimeraCoder/gojson v1.1.0/go.mod h1:nYbTQlu6hv8PETM15J927yM0zGj3njIldp72UT1MqSw=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905 h1:JG0OqQLCILn6ywoXJncu+/MFTTapP3aIIDDqB593HMc=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905/go.mod h1:hTreU6x9m2IP2h8e0TGrSzAXSCI3lxic8/JT5CMknjY=
|
||||
github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20191122014323-8cc8f217b23a h1:Y7Aia4DpAF6Kr7RH7cquqiQ+7xjOQdkcR/FalKyjd6w=
|
||||
@@ -109,7 +110,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -190,6 +190,8 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
@@ -221,15 +223,8 @@ github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5j
|
||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
|
||||
github.com/lucas-clemente/quic-go v0.11.0 h1:R7uxGrBWWSp817cdhkrunFsOA26vadf4EI9slWzkjlQ=
|
||||
github.com/lucas-clemente/quic-go v0.11.0/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
|
||||
github.com/lucas-clemente/quic-go v0.13.1 h1:CxtJTXQIh2aboCPk0M6vf530XOov6DZjVBiSE3nSj8s=
|
||||
github.com/lucas-clemente/quic-go v0.13.1/go.mod h1:Vn3/Fb0/77b02SGhQk36KzOUmXgVpFfizUfW5WMaqyU=
|
||||
github.com/marten-seemann/chacha20 v0.2.0 h1:f40vqzzx+3GdOmzQoItkLX5WLvHgPgyYqFFIO5Gh4hQ=
|
||||
github.com/marten-seemann/chacha20 v0.2.0/go.mod h1:HSdjFau7GzYRj+ahFNwsO3ouVJr1HFkWoEwNDb4TMtE=
|
||||
github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI=
|
||||
github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
|
||||
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/marten-seemann/qtls v0.4.1 h1:YlT8QP3WCCvvok7MGEZkMldXbyqgr8oFg5/n8Gtbkks=
|
||||
github.com/marten-seemann/qtls v0.4.1/go.mod h1:pxVXcHHw1pNIt8Qo0pwSYQEoZ8yYOOPXTCZLQQunvRc=
|
||||
github.com/marten-seemann/quic-conn v0.0.0-20190827120552-a06e62da55b7 h1:LHBrfRHvL1gANdnSvVXeEr79pJNj5H3jmODN1jeDjlI=
|
||||
github.com/marten-seemann/quic-conn v0.0.0-20190827120552-a06e62da55b7/go.mod h1:BTUDloYEkSYt9Yf98rSVDnIFrSJc04H3/6FfE+lsjNg=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
@@ -388,8 +383,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
|
||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
|
||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -407,7 +400,6 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -435,10 +427,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2 h1:/J2nHFg1MTqaRLFO7M+J78ASNsJoz3r0cvHBPQ77fsE=
|
||||
golang.org/x/sys v0.0.0-20191127021746-63cb32ae39b2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -463,7 +451,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo=
|
||||
google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
|
207
reflection/server_reflection.go
Normal file
207
reflection/server_reflection.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package reflection
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/ChimeraCoder/gojson"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
|
||||
var typeOfContext = reflect.TypeOf((*context.Context)(nil)).Elem()
|
||||
|
||||
var json = jsoniter.Config{
|
||||
TagKey: "-",
|
||||
}.Froze()
|
||||
|
||||
// ServiceInfo service info.
|
||||
type ServiceInfo struct {
|
||||
Name string
|
||||
PkgPath string
|
||||
Methods []*MethodInfo
|
||||
}
|
||||
|
||||
// MethodInfo method info
|
||||
type MethodInfo struct {
|
||||
Name string
|
||||
ReqName string
|
||||
Req string
|
||||
ReplyName string
|
||||
Reply string
|
||||
}
|
||||
|
||||
var siTemplate = `package {{.PkgPath}}
|
||||
|
||||
type {{.Name}} struct{}
|
||||
{{$name := .Name}}
|
||||
{{range .Methods}}
|
||||
{{.Req}}
|
||||
{{.Reply}}
|
||||
type (s *{{$name}}) {{.Name}}(ctx context.Context, arg *{{.ReqName}}, reply *{{.ReplyName}}) error {
|
||||
return nil
|
||||
}
|
||||
{{end}}
|
||||
`
|
||||
|
||||
func (si ServiceInfo) String() string {
|
||||
tpl := template.Must(template.New("service").Parse(siTemplate))
|
||||
var buf bytes.Buffer
|
||||
tpl.Execute(&buf, si)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type Reflection struct {
|
||||
Services map[string]*ServiceInfo
|
||||
}
|
||||
|
||||
func New() *Reflection {
|
||||
return &Reflection{
|
||||
Services: make(map[string]*ServiceInfo),
|
||||
}
|
||||
}
|
||||
func (r *Reflection) Register(name string, rcvr interface{}, metadata string) error {
|
||||
var si = &ServiceInfo{}
|
||||
|
||||
val := reflect.ValueOf(rcvr)
|
||||
typ := reflect.TypeOf(rcvr)
|
||||
vTyp := reflect.Indirect(val).Type()
|
||||
si.Name = vTyp.Name()
|
||||
pkg := vTyp.PkgPath()
|
||||
if strings.Index(pkg, ".") > 0 {
|
||||
pkg = pkg[strings.LastIndex(pkg, ".")+1:]
|
||||
}
|
||||
si.PkgPath = filepath.Base(pkg)
|
||||
|
||||
for m := 0; m < val.NumMethod(); m++ {
|
||||
method := typ.Method(m)
|
||||
mtype := method.Type
|
||||
|
||||
if method.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
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 !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 !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
|
||||
}
|
||||
|
||||
mi := &MethodInfo{}
|
||||
mi.Name = method.Name
|
||||
|
||||
if argType.Kind() == reflect.Ptr {
|
||||
argType = argType.Elem()
|
||||
}
|
||||
replyType = replyType.Elem()
|
||||
|
||||
mi.ReqName = argType.Name()
|
||||
mi.Req = generateTypeDefination(mi.ReqName, si.PkgPath, generateJSON(argType))
|
||||
mi.ReplyName = replyType.Name()
|
||||
mi.Reply = generateTypeDefination(mi.ReqName, si.PkgPath, generateJSON(replyType))
|
||||
|
||||
si.Methods = append(si.Methods, mi)
|
||||
}
|
||||
|
||||
if len(si.Methods) > 0 {
|
||||
r.Services[si.Name] = si
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Reflection) GetService(ctx context.Context, s string, reply *string) error {
|
||||
si, ok := r.Services[s]
|
||||
if !ok {
|
||||
return fmt.Errorf("not found service %s", s)
|
||||
}
|
||||
*reply = si.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Reflection) GetServices(ctx context.Context, s string, reply *string) error {
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
var pkg = `package `
|
||||
|
||||
for _, si := range r.Services {
|
||||
if pkg == `` {
|
||||
pkg = pkg + si.PkgPath + "\n\n"
|
||||
}
|
||||
buf.WriteString(strings.ReplaceAll(si.String(), pkg, ""))
|
||||
}
|
||||
|
||||
if pkg != `package ` {
|
||||
*reply = pkg + buf.String()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateTypeDefination(name, pkg string, jsonValue string) string {
|
||||
if jsonValue == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
r := strings.NewReader(jsonValue)
|
||||
output, err := gojson.Generate(r, gojson.ParseJson, name, pkg, nil, false, false)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
rt := strings.ReplaceAll(string(output), "``", "")
|
||||
return strings.ReplaceAll(rt, "package "+pkg+"\n\n", "")
|
||||
}
|
||||
|
||||
func generateJSON(typ reflect.Type) string {
|
||||
v := reflect.New(typ).Interface()
|
||||
|
||||
data, _ := json.Marshal(v)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func isExported(name string) bool {
|
||||
rune, _ := utf8.DecodeRuneInString(name)
|
||||
return unicode.IsUpper(rune)
|
||||
}
|
||||
|
||||
func isExportedOrBuiltinType(t reflect.Type) bool {
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
return isExported(t.Name()) || t.PkgPath() == ""
|
||||
}
|
28
reflection/server_reflection_test.go
Normal file
28
reflection/server_reflection_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package reflection
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
|
||||
testutils "github.com/smallnest/rpcx/_testutils"
|
||||
)
|
||||
|
||||
type PBArith int
|
||||
|
||||
func (t *PBArith) Mul(ctx context.Context, args *testutils.ProtoArgs, reply *testutils.ProtoReply) error {
|
||||
reply.C = args.A * args.B
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestReflection_Register(t *testing.T) {
|
||||
r := New()
|
||||
arith := PBArith(0)
|
||||
err := r.Register("Arith", &arith, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pretty.Println(r.Services["PBArith"].String())
|
||||
}
|
Reference in New Issue
Block a user