diff --git a/go.mod b/go.mod index c2a61f2db1484338bba7dd1bf00a9ff9de2125df..59c91607dc6a0db3add4884d90645a72cd4d880c 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ require ( github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190802083043-4cd0c391755e // indirect github.com/apache/dubbo-go-hessian2 v1.2.5-0.20191029001541-894e45c9aaaa + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect github.com/coreos/bbolt v1.3.3 // indirect github.com/coreos/etcd v3.3.13+incompatible @@ -18,6 +19,7 @@ require ( github.com/go-errors/errors v1.0.1 // indirect github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 + github.com/golang/protobuf v1.3.2 github.com/google/btree v1.0.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect diff --git a/protocol/grpc/client.go b/protocol/grpc/client.go index 3e3920fce2b6dc442327491aaf3efff3281b2220..39465953c3529fed45999c30711656ec3a6d40f9 100644 --- a/protocol/grpc/client.go +++ b/protocol/grpc/client.go @@ -35,20 +35,23 @@ type Client struct { } func NewClient(impl interface{}, url common.URL) *Client { - conn, err := grpc.Dial(url.Location, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { panic(err) } - in := []reflect.Value{} - in = append(in, reflect.ValueOf(conn)) - method := reflect.ValueOf(impl).MethodByName("GetDubboStub") - res := method.Call(in) - invoker := res[0].Interface() + invoker := getInvoker(impl, conn) return &Client{ ClientConn: conn, invoker: reflect.ValueOf(invoker), } } + +func getInvoker(impl interface{}, conn *grpc.ClientConn) interface{} { + in := []reflect.Value{} + in = append(in, reflect.ValueOf(conn)) + method := reflect.ValueOf(impl).MethodByName("GetDubboStub") + res := method.Call(in) + return res[0].Interface() +} \ No newline at end of file diff --git a/protocol/grpc/client_test.go b/protocol/grpc/client_test.go new file mode 100644 index 0000000000000000000000000000000000000000..21800a9f6df356b66f4f3e5f2cd9e42e874ff5e5 --- /dev/null +++ b/protocol/grpc/client_test.go @@ -0,0 +1,51 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpc + +import ( + //"context" + "reflect" + "testing" + + "github.com/bmizerany/assert" + "google.golang.org/grpc" + + "github.com/apache/dubbo-go/protocol/grpc/internal" +) + +//type GrpcGreeterImpl struct { +// SayHello func(ctx context.Context, in *internal.HelloRequest, out *internal.HelloReply) error +//} +// +//func (u *GrpcGreeterImpl) Reference() string { +// return "GrpcGreeterImpl" +//} +// +//func (u *GrpcGreeterImpl) GetDubboStub(cc *grpc.ClientConn) internal.GreeterClient { +// return internal.NewGreeterClient(cc) +//} + +func TestGetInvoker(t *testing.T) { + var conn *grpc.ClientConn + var impl *internal.GrpcGreeterImpl + invoker := getInvoker(impl, conn) + + i := reflect.TypeOf(invoker) + expected := reflect.TypeOf(internal.NewGreeterClient(nil)) + assert.Equal(t, i, expected) +} diff --git a/protocol/grpc/common_test.go b/protocol/grpc/common_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1669513471498235be48b016f67dd2a440124640 --- /dev/null +++ b/protocol/grpc/common_test.go @@ -0,0 +1,112 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpc + +import ( + "context" + "fmt" +) + +import ( + native_grpc "google.golang.org/grpc" +) + +import ( + "github.com/apache/dubbo-go/config" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/grpc/internal" + "github.com/apache/dubbo-go/protocol/invocation" +) + + +func addService() { + config.SetProviderService(NewGreeterProvider()) +} + +type GreeterProvider struct { + *GreeterProviderBase +} + +func NewGreeterProvider() *GreeterProvider { + return &GreeterProvider{ + GreeterProviderBase: &GreeterProviderBase{}, + } +} + +func (g *GreeterProvider) SayHello(ctx context.Context, req *internal.HelloRequest) (reply *internal.HelloReply, err error) { + fmt.Printf("req: %v", req) + return &internal.HelloReply{Message: "this is message from reply"}, nil +} + +func (g *GreeterProvider) Reference() string { + return "GrpcGreeterImpl" +} + +// code generated by greeter.go +type GreeterProviderBase struct { + proxyImpl protocol.Invoker +} + +func (g *GreeterProviderBase) SetProxyImpl(impl protocol.Invoker) { + g.proxyImpl = impl +} + +func (g *GreeterProviderBase) GetProxyImpl() protocol.Invoker { + return g.proxyImpl +} + +func (g *GreeterProviderBase) ServiceDesc() *native_grpc.ServiceDesc { + return &native_grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*internal.GreeterServer)(nil), + Methods: []native_grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _DUBBO_Greeter_SayHello_Handler, + }, + }, + Streams: []native_grpc.StreamDesc{}, + Metadata: "helloworld.proto", + } +} + +func _DUBBO_Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor native_grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(internal.HelloRequest) + if err := dec(in); err != nil { + return nil, err + } + base := srv.(DubboGrpcService) + + args := []interface{}{} + args = append(args, in) + invo := invocation.NewRPCInvocation("SayHello", args, nil) + + if interceptor == nil { + result := base.GetProxyImpl().Invoke(invo) + return result.Result(), result.Error() + } + info := &native_grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/helloworld.Greeter/SayHello", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + result := base.GetProxyImpl().Invoke(invo) + return result.Result(), result.Error() + } + return interceptor(ctx, in, info, handler) +} diff --git a/protocol/grpc/grpc_protocol_test.go b/protocol/grpc/grpc_protocol_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a293e1073d9b0f460b4a66ab97ee704090992001 --- /dev/null +++ b/protocol/grpc/grpc_protocol_test.go @@ -0,0 +1,113 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package grpc + +import ( + "context" + "log" + "net" + "testing" + "time" +) + +import ( + "github.com/stretchr/testify/assert" + native_grpc "google.golang.org/grpc" +) + +import ( + "github.com/apache/dubbo-go/common" + "github.com/apache/dubbo-go/protocol" + "github.com/apache/dubbo-go/protocol/grpc/internal" +) + +func TestGrpcProtocol_Export(t *testing.T) { + // Export + addService() + + proto := GetProtocol() + url, err := common.NewURL(context.Background(), "grpc://127.0.0.1:20000/GrpcGreeterImpl?accesslog=&app.version=0.0.1&application=BDTService&bean.name=GrpcGreeterImpl&cluster=failover&environment=dev&execute.limit=&execute.limit.rejected.handler=&group=&interface=io.grpc.examples.helloworld.GreeterGrpc%24IGreeter&loadbalance=random&methods.SayHello.loadbalance=random&methods.SayHello.retries=1&methods.SayHello.tps.limit.interval=&methods.SayHello.tps.limit.rate=&methods.SayHello.tps.limit.strategy=&methods.SayHello.weight=0&module=dubbogo+say-hello+client&name=BDTService&organization=ikurento.com&owner=ZX®istry.role=3&retries=&service.filter=echo%2Ctoken%2Caccesslog%2Ctps%2Cexecute%2Cpshutdown×tamp=1576923717&tps.limit.interval=&tps.limit.rate=&tps.limit.rejected.handler=&tps.limit.strategy=&tps.limiter=&version=&warmup=100") + assert.NoError(t, err) + exporter := proto.Export(protocol.NewBaseInvoker(url)) + time.Sleep(time.Second) + + // make sure url + eq := exporter.GetInvoker().GetUrl().URLEqual(url) + assert.True(t, eq) + + // make sure exporterMap after 'Unexport' + _, ok := proto.(*GrpcProtocol).ExporterMap().Load(url.ServiceKey()) + assert.True(t, ok) + exporter.Unexport() + _, ok = proto.(*GrpcProtocol).ExporterMap().Load(url.ServiceKey()) + assert.False(t, ok) + + // make sure serverMap after 'Destroy' + _, ok = proto.(*GrpcProtocol).serverMap[url.Location] + assert.True(t, ok) + proto.Destroy() + _, ok = proto.(*GrpcProtocol).serverMap[url.Location] + assert.False(t, ok) +} + +// server is used to implement helloworld.GreeterServer. +type server struct { + internal.UnimplementedGreeterServer +} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *internal.HelloRequest) (*internal.HelloReply, error) { + log.Printf("Received: %v", in.GetName()) + return &internal.HelloReply{Message: "Hello " + in.GetName()}, nil +} + +func initGrpcServer() { + port := ":20000" + + lis, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := native_grpc.NewServer() + internal.RegisterGreeterServer(s, &server{}) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} + +func TestGrpcProtocol_Refer(t *testing.T) { + go initGrpcServer() + time.Sleep(time.Second) + + proto := GetProtocol() + url, err := common.NewURL(context.Background(), "grpc://127.0.0.1:20000/GrpcGreeterImpl?accesslog=&anyhost=true&app.version=0.0.1&application=BDTService&async=false&bean.name=GrpcGreeterImpl&category=providers&cluster=failover&dubbo=dubbo-provider-golang-2.6.0&environment=dev&execute.limit=&execute.limit.rejected.handler=&generic=false&group=&interface=io.grpc.examples.helloworld.GreeterGrpc%24IGreeter&ip=192.168.1.106&loadbalance=random&methods.SayHello.loadbalance=random&methods.SayHello.retries=1&methods.SayHello.tps.limit.interval=&methods.SayHello.tps.limit.rate=&methods.SayHello.tps.limit.strategy=&methods.SayHello.weight=0&module=dubbogo+say-hello+client&name=BDTService&organization=ikurento.com&owner=ZX&pid=49427&reference.filter=cshutdown®istry.role=3&remote.timestamp=1576923717&retries=&service.filter=echo%2Ctoken%2Caccesslog%2Ctps%2Cexecute%2Cpshutdown&side=provider×tamp=1576923740&tps.limit.interval=&tps.limit.rate=&tps.limit.rejected.handler=&tps.limit.strategy=&tps.limiter=&version=&warmup=100!") + assert.NoError(t, err) + var impl *internal.GrpcGreeterImpl + invoker := proto.Refer(url, impl) + + // make sure url + eq := invoker.GetUrl().URLEqual(url) + assert.True(t, eq) + + // make sure invokers after 'Destroy' + invokersLen := len(proto.(*GrpcProtocol).Invokers()) + assert.Equal(t, 1, invokersLen) + proto.Destroy() + invokersLen = len(proto.(*GrpcProtocol).Invokers()) + assert.Equal(t, 0, invokersLen) +} diff --git a/protocol/grpc/internal/client.go b/protocol/grpc/internal/client.go new file mode 100644 index 0000000000000000000000000000000000000000..647fe50f4412fe795bb3a3da411c23b18a4b63a4 --- /dev/null +++ b/protocol/grpc/internal/client.go @@ -0,0 +1,38 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "context" +) + +import ( + "google.golang.org/grpc" +) + +type GrpcGreeterImpl struct { + SayHello func(ctx context.Context, in *HelloRequest, out *HelloReply) error +} + +func (u *GrpcGreeterImpl) Reference() string { + return "GrpcGreeterImpl" +} + +func (u *GrpcGreeterImpl) GetDubboStub(cc *grpc.ClientConn) GreeterClient { + return NewGreeterClient(cc) +} diff --git a/protocol/grpc/internal/helloworld.pb.go b/protocol/grpc/internal/helloworld.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..83c2bc253502c95756cd8c65322b56944295f8d2 --- /dev/null +++ b/protocol/grpc/internal/helloworld.pb.go @@ -0,0 +1,210 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: helloworld.proto + +package internal + +import ( + "context" + "fmt" + "math" + + "github.com/golang/protobuf/proto" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// The request message containing the user's name. +type HelloRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HelloRequest) Reset() { *m = HelloRequest{} } +func (m *HelloRequest) String() string { return proto.CompactTextString(m) } +func (*HelloRequest) ProtoMessage() {} +func (*HelloRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_17b8c58d586b62f2, []int{0} +} + +func (m *HelloRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HelloRequest.Unmarshal(m, b) +} +func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic) +} +func (m *HelloRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HelloRequest.Merge(m, src) +} +func (m *HelloRequest) XXX_Size() int { + return xxx_messageInfo_HelloRequest.Size(m) +} +func (m *HelloRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HelloRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HelloRequest proto.InternalMessageInfo + +func (m *HelloRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// The response message containing the greetings +type HelloReply struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HelloReply) Reset() { *m = HelloReply{} } +func (m *HelloReply) String() string { return proto.CompactTextString(m) } +func (*HelloReply) ProtoMessage() {} +func (*HelloReply) Descriptor() ([]byte, []int) { + return fileDescriptor_17b8c58d586b62f2, []int{1} +} + +func (m *HelloReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HelloReply.Unmarshal(m, b) +} +func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic) +} +func (m *HelloReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_HelloReply.Merge(m, src) +} +func (m *HelloReply) XXX_Size() int { + return xxx_messageInfo_HelloReply.Size(m) +} +func (m *HelloReply) XXX_DiscardUnknown() { + xxx_messageInfo_HelloReply.DiscardUnknown(m) +} + +var xxx_messageInfo_HelloReply proto.InternalMessageInfo + +func (m *HelloReply) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func init() { + proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") + proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") +} + +func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_17b8c58d586b62f2) } + +var fileDescriptor_17b8c58d586b62f2 = []byte{ + // 175 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, + 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, + 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, + 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, + 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, + 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, + 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, + 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6, + 0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9, + 0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb, + 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// GreeterClient is the client API for Greeter service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type GreeterClient interface { + // Sends a greeting + SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) +} + +type greeterClient struct { + cc *grpc.ClientConn +} + +func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { + return &greeterClient{cc} +} + +func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { + out := new(HelloReply) + err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GreeterServer is the server API for Greeter service. +type GreeterServer interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) +} + +// UnimplementedGreeterServer can be embedded to have forward compatible implementations. +type UnimplementedGreeterServer struct { +} + +func (*UnimplementedGreeterServer) SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error) { + return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") +} + +func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, srv) +} + +func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HelloRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GreeterServer).SayHello(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/helloworld.Greeter/SayHello", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Greeter_serviceDesc = grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "helloworld.proto", +} diff --git a/protocol/grpc/server.go b/protocol/grpc/server.go index cc70a9112d9cadd68b4ed175487654c2954246b6..0777c09bb46ed370553187048adfde1b219b1eb9 100644 --- a/protocol/grpc/server.go +++ b/protocol/grpc/server.go @@ -30,6 +30,7 @@ import ( import ( "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" + "github.com/apache/dubbo-go/common/logger" "github.com/apache/dubbo-go/config" "github.com/apache/dubbo-go/protocol" ) @@ -88,9 +89,11 @@ func (s *Server) Start(url common.URL) { server.RegisterService(ds.ServiceDesc(), service) s.grpcServer = server - if err = server.Serve(lis); err != nil { - panic(err) - } + go func() { + if err = server.Serve(lis); err != nil { + logger.Errorf("server serve failed with err: %v", err) + } + }() } func (s *Server) Stop() {