func confirmOne(ack, nack chan uint64) {
	log.Printf("waiting for confirmation of one publishing")
	select {
	case tag := <-ack:
		log.Printf("confirmed delivery with delivery tag: %d", tag)
	case tag := <-nack:
		log.Printf("failed delivery of delivery tag: %d", tag)
	}
}
One would typically keep a channel of publishings, a sequence number, and a
set of unacknowledged sequence numbers and loop until the publishing channel
is closed.
package main
import (
	"fmt"
	"github.com/streadway/amqp"
	"log"
)
type Producer struct {
	connection *amqp.Connection
	channel    *amqp.Channel
	tag        string
	done       chan error
}
func NewProducer(amqpURI, exchange, exchangeType, key, ctag string, reliable bool) (*Producer, error) {
	p := &Producer{
		connection: nil,
		channel:    nil,
		tag:        ctag,
		done:       make(chan error),
	}
	var err error
	log.Printf("Connecting to %s", amqpURI)
	p.connection, err = amqp.Dial(amqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: ", err)
	}
	log.Printf("Getting Channel ")
	p.channel, err = p.connection.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: ", err)
	}
	log.Printf("Declaring Exchange (%s)", exchange)
	if err := p.channel.ExchangeDeclare(
		exchange,      
		exchangeType,  
		true,          
		false,         
		false,         
		false,         
		nil,           
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}
	return p, nil
}
func (p *Producer) Publish(exchange, routingKey, body string) error {
	log.Printf("Publishing %s (%dB)", body, len(body))
	if err := p.channel.Publish(
		exchange,    
		routingKey,  
		false,       
		false,       
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "text/plain",
			ContentEncoding: "",
			Body:            []byte(body),
			DeliveryMode:    amqp.Transient,  
			Priority:        0,               
		},
	); err != nil {
		return fmt.Errorf("Exchange Publish: ", err)
	}
	return nil
}