func (c *Client) Shutdown() {
	c.ac.shutdown()
}
Shutdown shuts down the client gracefully. Using this method will ensure
that all replies sent by the RPC servers to the client will be received by
the latter.
package rpcmq
import (
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"time"
	"github.com/streadway/amqp"
)
type Client struct {
	msgsName     string
	repliesName  string
	exchangeName string
	exchangeKind string
	ac           *amqpClient
	msgsQueue    amqp.Queue
	repliesQueue amqp.Queue
	mandatory    bool
	deliveries   <-chan amqp.Delivery
	results      chan Result
	DeliveryMode DeliveryMode
	TLSConfig *tls.Config
}
type Result struct {
	UUID string
	Data []byte
	Err  string
}
type rpcMsg struct {
	Method string
	Data   []byte
}
func NewClient(uri, msgsQueue, repliesQueue, exchange, kind string) *Client {
	var mandatory bool
	if kind == "fanout" {
		msgsQueue = ""  
		mandatory = false
	} else {
		mandatory = true
	}
	c := &Client{
		msgsName:     msgsQueue,
		repliesName:  repliesQueue,
		exchangeName: exchange,
		exchangeKind: kind,
		mandatory:    mandatory,
		ac:           newAmqpClient(uri),
		results:      make(chan Result),
		DeliveryMode: Persistent,
	}
	c.ac.setupFunc = c.setup
	return c
}
func (c *Client) Init() error {
	c.ac.tlsConfig = c.TLSConfig
	if err := c.ac.init(); err != nil {
		return err
	}
	return c.setup()
}
func (c *Client) setup() error {
	err := c.ac.channel.ExchangeDeclare(
		c.exchangeName,  
		c.exchangeKind,  
		true,            
		false,           
		false,           
		false,           
		nil,             
	)
	if err != nil {
		return fmt.Errorf("ExchangeDeclare: %v", err)
	}
	if c.exchangeKind != "fanout" {
		c.msgsQueue, err = c.ac.channel.QueueDeclare(
			c.msgsName,  
			true,        
			false,       
			false,       
			false,       
			nil,         
		)
		if err != nil {
			return fmt.Errorf("QueueDeclare: %v", err)
		}
		err = c.ac.channel.QueueBind(
			c.msgsQueue.Name,  
			c.msgsQueue.Name,  
			c.exchangeName,    
			false,             
			nil,               
		)
		if err != nil {
			return fmt.Errorf("QueueBind: %v", err)
		}
	}
	c.repliesQueue, err = c.ac.channel.QueueDeclare(
		c.repliesName,  
		true,           
		false,          
		false,          
		false,          
		nil,            
	)
	if err != nil {
		return fmt.Errorf("QueueDeclare: %v", err)
	}
	c.ac.consumerTag, err = uuid()
	if err != nil {
		return fmt.Errorf("UUID: %v", err)
	}
	c.deliveries, err = c.ac.channel.Consume(
		c.repliesQueue.Name,  
		c.ac.consumerTag,     
		false,                
		false,                
		false,                
		false,                
		nil,                  
	)
	if err != nil {
		return fmt.Errorf("Queue Consume: %v", err)
	}
	go c.getDeliveries()
	return nil
}
func (c *Client) getDeliveries() {
	for d := range c.deliveries {
		if d.CorrelationId == "" {
			d.Nack(false, false)  
			logf("dropped message: %+v", d)
			continue
		}
		var r Result
		if err := json.Unmarshal(d.Body, &r); err != nil {
			d.Nack(false, false)  
			logf("dropped message: %+v", d)
			continue
		}
		c.results <- r
		d.Ack(false)
	}
	c.ac.done <- true
}