2020-08-23 20:37:22 +03:00
|
|
|
// Package grpc provides a grpc transport
|
2021-10-28 00:58:31 +03:00
|
|
|
package grpc // import "go.unistack.org/micro-network-transport-grpc/v3"
|
2020-08-23 20:37:22 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/tls"
|
|
|
|
"net"
|
|
|
|
|
2021-10-28 00:58:31 +03:00
|
|
|
pb "go.unistack.org/micro-network-transport-grpc/v3/proto"
|
|
|
|
"go.unistack.org/micro/v3/network/transport"
|
|
|
|
mnet "go.unistack.org/micro/v3/util/net"
|
2020-08-23 20:37:22 +03:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
)
|
|
|
|
|
|
|
|
type grpcTransport struct {
|
|
|
|
opts transport.Options
|
|
|
|
}
|
|
|
|
|
|
|
|
type grpcTransportListener struct {
|
|
|
|
listener net.Listener
|
|
|
|
tls *tls.Config
|
2020-11-06 10:59:47 +03:00
|
|
|
opts transport.ListenOptions
|
2020-08-23 20:37:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransportListener) Addr() string {
|
|
|
|
return t.listener.Addr().String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransportListener) Close() error {
|
|
|
|
return t.listener.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransportListener) Accept(fn func(transport.Socket)) error {
|
|
|
|
var opts []grpc.ServerOption
|
|
|
|
|
|
|
|
// setup tls if specified
|
2021-02-18 22:33:08 +03:00
|
|
|
if t.tls != nil {
|
2020-11-05 23:51:00 +03:00
|
|
|
creds := credentials.NewTLS(t.tls)
|
2020-08-23 20:37:22 +03:00
|
|
|
opts = append(opts, grpc.Creds(creds))
|
|
|
|
}
|
|
|
|
|
|
|
|
// new service
|
|
|
|
srv := grpc.NewServer(opts...)
|
|
|
|
|
|
|
|
// register service
|
|
|
|
pb.RegisterTransportServer(srv, µTransport{addr: t.listener.Addr().String(), fn: fn})
|
|
|
|
|
|
|
|
// start serving
|
|
|
|
return srv.Serve(t.listener)
|
|
|
|
}
|
|
|
|
|
2020-11-06 10:59:47 +03:00
|
|
|
func (t *grpcTransport) Dial(ctx context.Context, addr string, opts ...transport.DialOption) (transport.Client, error) {
|
|
|
|
dopts := transport.NewDialOptions(opts...)
|
2020-08-23 20:37:22 +03:00
|
|
|
|
|
|
|
options := []grpc.DialOption{}
|
|
|
|
|
2021-02-18 22:33:08 +03:00
|
|
|
if t.opts.TLSConfig != nil {
|
|
|
|
creds := credentials.NewTLS(t.opts.TLSConfig)
|
2020-08-23 20:37:22 +03:00
|
|
|
options = append(options, grpc.WithTransportCredentials(creds))
|
|
|
|
} else {
|
|
|
|
options = append(options, grpc.WithInsecure())
|
|
|
|
}
|
|
|
|
|
|
|
|
// dial the server
|
2020-11-06 10:59:47 +03:00
|
|
|
ctx, cancel := context.WithTimeout(ctx, dopts.Timeout)
|
2020-08-23 20:37:22 +03:00
|
|
|
defer cancel()
|
|
|
|
conn, err := grpc.DialContext(ctx, addr, options...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// create stream
|
|
|
|
stream, err := pb.NewTransportClient(conn).Stream(context.Background())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// return a client
|
|
|
|
return &grpcTransportClient{
|
|
|
|
conn: conn,
|
|
|
|
stream: stream,
|
|
|
|
local: "localhost",
|
|
|
|
remote: addr,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2020-11-06 10:59:47 +03:00
|
|
|
func (t *grpcTransport) Listen(ctx context.Context, addr string, opts ...transport.ListenOption) (transport.Listener, error) {
|
|
|
|
options := transport.NewListenOptions(opts...)
|
2020-08-23 20:37:22 +03:00
|
|
|
|
|
|
|
ln, err := mnet.Listen(addr, func(addr string) (net.Listener, error) {
|
|
|
|
return net.Listen("tcp", addr)
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &grpcTransportListener{
|
|
|
|
listener: ln,
|
|
|
|
tls: t.opts.TLSConfig,
|
2020-11-06 10:59:47 +03:00
|
|
|
opts: options,
|
2020-08-23 20:37:22 +03:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransport) Init(opts ...transport.Option) error {
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&t.opts)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransport) Options() transport.Options {
|
|
|
|
return t.opts
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *grpcTransport) String() string {
|
|
|
|
return "grpc"
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTransport(opts ...transport.Option) transport.Transport {
|
|
|
|
var options transport.Options
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
return &grpcTransport{opts: options}
|
|
|
|
}
|