github.com/turingchain2020/turingchain@v1.1.21/rpc/grpcclient/resolver.go (about)

     1  package grpcclient
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net"
     7  	"strings"
     8  
     9  	"google.golang.org/grpc/resolver"
    10  )
    11  
    12  // Scheme 自定义grpc负载局衡名
    13  const scheme = "multiple"
    14  
    15  // Separator url分隔符
    16  const separator = ":///"
    17  
    18  // MultiPleHostsBalancerPrefix url前缀
    19  const multiPleHostsBalancerPrefix = scheme + separator
    20  
    21  // defaultGrpcPort 默认grpc端口
    22  const defaultGrpcPort = "9672"
    23  
    24  func parseTarget(target, defaultPort string) (host, port string, err error) {
    25  	if target == "" {
    26  		return "", "", errors.New("multiple resolver: missing address")
    27  	}
    28  	if ip := net.ParseIP(target); ip != nil {
    29  		return target, defaultPort, nil
    30  	}
    31  	if host, port, err = net.SplitHostPort(target); err == nil {
    32  		if port == "" {
    33  			return "", "", errors.New("multiple resolver: missing port after port-separator colon")
    34  		}
    35  		if host == "" {
    36  			host = "localhost"
    37  		}
    38  		return host, port, nil
    39  	}
    40  	if host, port, err = net.SplitHostPort(target + ":" + defaultPort); err == nil {
    41  		return host, port, nil
    42  	}
    43  	return "", "", fmt.Errorf("invalid target address %v, error info: %v", target, err)
    44  }
    45  
    46  type multipleBuilder struct{}
    47  
    48  func (*multipleBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
    49  	r := &multipleResolver{
    50  		target: target,
    51  		cc:     cc,
    52  	}
    53  
    54  	urls := strings.Split(target.Endpoint, ",")
    55  	if len(urls) < 1 {
    56  		return nil, fmt.Errorf("invalid target address %v", target)
    57  	}
    58  
    59  	for _, url := range urls {
    60  		host, port, err := parseTarget(url, defaultGrpcPort)
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  
    65  		if host != "" {
    66  			r.addrs = append(r.addrs, resolver.Address{Addr: host + ":" + port})
    67  		}
    68  	}
    69  	r.start()
    70  	return r, nil
    71  }
    72  
    73  func (*multipleBuilder) Scheme() string {
    74  	return scheme
    75  }
    76  
    77  type multipleResolver struct {
    78  	target resolver.Target
    79  	cc     resolver.ClientConn
    80  	addrs  []resolver.Address
    81  }
    82  
    83  func (r *multipleResolver) start() {
    84  	r.cc.NewAddress(r.addrs)
    85  }
    86  
    87  func (*multipleResolver) ResolveNow(o resolver.ResolveNowOptions) {}
    88  
    89  func (*multipleResolver) Close() {}
    90  
    91  func init() {
    92  	resolver.Register(&multipleBuilder{})
    93  }
    94  
    95  //NewMultipleURL 创建url
    96  func NewMultipleURL(url string) string {
    97  	return multiPleHostsBalancerPrefix + url
    98  }