diff --git a/server/grpc/grpc.go b/server/grpc/grpc.go index 5aed508e..67be638b 100644 --- a/server/grpc/grpc.go +++ b/server/grpc/grpc.go @@ -171,6 +171,17 @@ func (g *grpcServer) getGrpcOptions() []grpc.ServerOption { return opts } +func (g *grpcServer) getListener() net.Listener { + if g.opts.Context != nil { + if v := g.opts.Context.Value(netListener{}); v != nil { + if l, ok := v.(net.Listener); ok { + return l + } + } + } + return nil +} + func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) error { if g.wg != nil { g.wg.Add(1) @@ -788,9 +799,16 @@ func (g *grpcServer) Start() error { config := g.Options() // micro: config.Transport.Listen(config.Address) - ts, err := net.Listen("tcp", config.Address) - if err != nil { - return err + var ts net.Listener + + if l := g.getListener(); l != nil { + ts = l + } else { + var err error + ts, err = net.Listen("tcp", config.Address) + if err != nil { + return err + } } log.Logf("Server [grpc] Listening on %s", ts.Addr().String()) diff --git a/server/grpc/options.go b/server/grpc/options.go index b411b88e..a46b9147 100644 --- a/server/grpc/options.go +++ b/server/grpc/options.go @@ -3,6 +3,7 @@ package grpc import ( "context" "crypto/tls" + "net" "github.com/micro/go-micro/v2/broker" "github.com/micro/go-micro/v2/codec" @@ -14,9 +15,10 @@ import ( ) type codecsKey struct{} -type tlsAuth struct{} -type maxMsgSizeKey struct{} type grpcOptions struct{} +type netListener struct{} +type maxMsgSizeKey struct{} +type tlsAuth struct{} // gRPC Codec to be used to encode/decode requests for a given content type func Codec(contentType string, c encoding.Codec) server.Option { @@ -43,6 +45,16 @@ func AuthTLS(t *tls.Config) server.Option { } } +// Listener specifies the net.Listener to use instead of the default +func Listener(l net.Listener) server.Option { + return func(o *server.Options) { + if o.Context == nil { + o.Context = context.Background() + } + o.Context = context.WithValue(o.Context, netListener{}, l) + } +} + // Options to be used to configure gRPC options func Options(opts ...grpc.ServerOption) server.Option { return func(o *server.Options) {