package rabbitmq
import (
"fmt"
"github.com/pkg/errors"
"github.com/streadway/amqp"
)
/*************************RabbitMQ初始化start**********************/
// 除了simple 模式外、其他的模式都是由 队列 交换机 key 不同组合实现的
type RabbitMQ struct {
conn *amqp.Connection
channel *amqp.Channel
QueueName string //队列
Exchange string //交换机
Key string //key
MQUrl string //连接信息
}
// 创建RabbitMQ 实例
func newRabbitMQ(queueName, exchange, key string) (*RabbitMQ, error) {
rabbitMQ := &RabbitMQ{
QueueName: queueName,
Exchange: exchange,
Key: key,
MQUrl: "amqp://user:[email protected]:5672/", //Virtual host用的哪个库
}
var err error
// dial mq
rabbitMQ.conn, err = amqp.Dial(rabbitMQ.MQUrl)
rabbitMQ.failOnErr(err, "创建连接错误")
if err != nil {
return nil, errors.Wrap(err, "create connect error")
}
// get channel
rabbitMQ.channel, err = rabbitMQ.conn.Channel()
if err != nil {
return nil, errors.Wrap(err, "get channel err")
}
return rabbitMQ, nil
}
// 错误处理
func (r *RabbitMQ) failOnErr(err error, message string) {
if err != nil {
panic(fmt.Sprintf("%s:%s", err.Error(), message))
}
}
/****************RabbitMQ初始化end**********************************/
/************路由模式 start******************/
//创建RabbitMQ实例
func NewRabbitMQRouting(exchangeName string,routingKey string) *RabbitMQ {
//创建RabbitMQ实例
rabbitmq := NewRabbitMQ("",exchangeName,routingKey)
var err error
//获取connection
rabbitmq.conn, err = amqp.Dial(rabbitmq.Mqurl)
rabbitmq.failOnErr(err,"failed to connect rabbitmq!")
//获取channel
rabbitmq.channel, err = rabbitmq.conn.Channel()
rabbitmq.failOnErr(err, "failed to open a channel")
return rabbitmq
}
//路由模式发送消息
func (r *RabbitMQ) PublishRouting(message string ) {
//1.尝试创建交换机
err := r.channel.ExchangeDeclare(
r.Exchange,
//要改成direct
"direct",
true,
false,
false,
false,
nil,
)
r.failOnErr(err, "Failed to declare an excha"+
"nge")
//2.发送消息
err = r.channel.Publish(
r.Exchange,
//要设置
r.Key,
false,
false,
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(message),
})
}
//路由模式接受消息
func (r *RabbitMQ) RecieveRouting() {
//1.试探性创建交换机
err := r.channel.ExchangeDeclare(
r.Exchange,
//交换机类型
"direct",
true,
false,
false,
false,
nil,
)
r.failOnErr(err, "Failed to declare an exch"+
"ange")
//2.试探性创建队列,这里注意队列名称不要写
q, err := r.channel.QueueDeclare(
"", //随机生产队列名称
false,
false,
true,
false,
nil,
)
r.failOnErr(err, "Failed to declare a queue")
//绑定队列到 exchange 中
err = r.channel.QueueBind(
q.Name,
//需要绑定key
r.Key,
r.Exchange,
false,
nil)
//消费消息
messges, err := r.channel.Consume(
q.Name,
"",
true,
false,
false,
false,
nil,
)
forever := make(chan bool)
go func() {
for d := range messges {
log.Printf("Received a message: %s", d.Body)
}
}()
fmt.Println("退出请按 CTRL+C\n")
<-forever
}
package main
import "rabbitmq/RabbitMQ"
func main() {
imoocOne:=RabbitMQ.NewRabbitMQRouting("exImooc","imooc_one")
imoocOne.RecieveRouting()
}
package main
import "rabbitmq/RabbitMQ"
func main() {
imoocOne:=RabbitMQ.NewRabbitMQRouting("exImooc","imooc_two")
imoocOne.RecieveRouting()
}
package main
import (
"rabbitmq/RabbitMQ"
"strconv"
"time"
"fmt"
)
func main() {
imoocOne:=RabbitMQ.NewRabbitMQRouting("exImooc","imooc_one")
imoocTwo:=RabbitMQ.NewRabbitMQRouting("exImooc","imooc_two")
for i := 0; i <= 10; i++ {
imoocOne.PublishRouting("Hello imooc one!" + strconv.Itoa(i))
imoocTwo.PublishRouting("Hello imooc Two!" + strconv.Itoa(i))
time.Sleep(1 * time.Second)
fmt.Println(i)
}
}