func (client *Client) IsShutdown() bool {
	client.mutex.Lock()
	defer client.mutex.Unlock()
	return client.shutdown
}
IsShutdown client is shutdown or not.
package client
import (
	"bufio"
	"bytes"
	"context"
	"crypto/tls"
	"errors"
	"io"
	"net"
	"net/url"
	"strconv"
	"sync"
	"time"
	opentracing "github.com/opentracing/opentracing-go"
	circuit "github.com/rubyist/circuitbreaker"
	"github.com/kudoochui/kudos/rpcx/log"
	"github.com/kudoochui/kudos/rpcx/protocol"
	"github.com/kudoochui/kudos/rpcx/share"
	"go.opencensus.io/trace"
)
const (
	XVersion           = "X-RPCX-Version"
	XMessageType       = "X-RPCX-MesssageType"
	XHeartbeat         = "X-RPCX-Heartbeat"
	XOneway            = "X-RPCX-Oneway"
	XMessageStatusType = "X-RPCX-MessageStatusType"
	XSerializeType     = "X-RPCX-SerializeType"
	XMessageID         = "X-RPCX-MessageID"
	XServicePath       = "X-RPCX-ServicePath"
	XServiceMethod     = "X-RPCX-ServiceMethod"
	XMeta              = "X-RPCX-Meta"
	XErrorMessage      = "X-RPCX-ErrorMessage"
)
type ServiceError string
func (e ServiceError) Error() string {
	return string(e)
}
var DefaultOption = Option{
	Retries:             3,
	RPCPath:             share.DefaultRPCPath,
	ConnectTimeout:      10 * time.Second,
	SerializeType:       protocol.MsgPack,
	CompressType:        protocol.None,
	BackupLatency:       10 * time.Millisecond,
	MaxWaitForHeartbeat: 30 * time.Second,
	TCPKeepAlivePeriod:  time.Minute,
}
type Breaker interface {
	Call(func() error, time.Duration) error
	Fail()
	Success()
	Ready() bool
}
var CircuitBreaker Breaker = circuit.NewRateBreaker(0.95, 100)
var (
	ErrShutdown         = errors.New("connection is shut down")
	ErrUnsupportedCodec = errors.New("unsupported codec")
)
const (
	ReaderBuffsize = 16 * 1024
	WriterBuffsize = 16 * 1024
)
type seqKey struct{}
type RPCClient interface {
	Connect(network, address string) error
	Go(ctx context.Context, servicePath, serviceMethod string, session protocol.ISession, args interface{}, reply interface{}, done chan *Call) *Call
	Call(ctx context.Context, servicePath, serviceMethod string, session protocol.ISession, args interface{}, reply interface{}) error
	SendRaw(ctx context.Context, r *protocol.Message) (map[string]string, []byte, error)
	Close() error
	RemoteAddr() string
	RegisterServerMessageChan(ch chan<- *protocol.Message)
	UnregisterServerMessageChan()
	IsClosing() bool
	IsShutdown() bool
}
type Client struct {
	option Option
	Conn net.Conn
	r    *bufio.Reader
	mutex        sync.Mutex  
	seq          uint64
	pending      map[uint64]*Call
	closing      bool  
	shutdown     bool  
	pluginClosed bool  
	Plugins PluginContainer
	ServerMessageChanMu sync.RWMutex
	ServerMessageChan   chan<- *protocol.Message
}
func NewClient(option Option) *Client {
	return &Client{
		option: option,
	}
}
func (c *Client) RemoteAddr() string {
	return c.Conn.RemoteAddr().String()
}
type Option struct {
	Group string
	Retries int
	TLSConfig *tls.Config
	Block interface{}
	RPCPath string
	ConnectTimeout time.Duration
	IdleTimeout time.Duration
	BackupLatency time.Duration
	GenBreaker func() Breaker
	SerializeType protocol.SerializeType
	CompressType  protocol.CompressType
	Heartbeat bool
	HeartbeatInterval   time.Duration
	MaxWaitForHeartbeat time.Duration
	TCPKeepAlivePeriod time.Duration
}
type Call struct {
	ServicePath   string             
	ServiceMethod string             
	Metadata      map[string]string  
	ResMetadata   map[string]string
	session 	  protocol.ISession
	Args          interface{}  
	Reply         interface{}  
	Error         error        
	Done          chan *Call   
	Raw           bool         
}
func (call *Call) done() {
	select {
	case call.Done <- call:
	default:
		log.Debug("rpc: discarding Call reply due to insufficient Done chan capacity")
	}
}
func (client *Client) RegisterServerMessageChan(ch chan<- *protocol.Message) {
	client.ServerMessageChanMu.Lock()
	client.ServerMessageChan = ch
	client.ServerMessageChanMu.Unlock()
}
func (client *Client) UnregisterServerMessageChan() {
	client.ServerMessageChanMu.Lock()
	client.ServerMessageChan = nil
	client.ServerMessageChanMu.Unlock()
}
func (client *Client) IsClosing() bool {
	client.mutex.Lock()
	defer client.mutex.Unlock()
	return client.closing
}