xxxxxxxxxx
package helpers
import (
"context"
"log"
"os"
"time"
"github.com/google/uuid"
jsoniter "github.com/json-iterator/go"
ampq "github.com/rabbitmq/amqp091-go"
)
type queueResponse struct {
Items interface{}
}
type rabbitmqInterface interface {
Consumer(eventName string) (queueResponse, bool)
}
type rabbitmq struct {
connection *ampq.Connection
}
var (
rbConfig = ampq.Config{}
rbResponse = queueResponse{}
exchangeName = "idrm.direct"
routingKey = "a.b.c"
isPublished = true
isConsumed = true
json = jsoniter.ConfigCompatibleWithStandardLibrary
)
func NewRabbitMQ() rabbitmqInterface {
var (
protocol = os.Getenv("RABBITMQ_PROTOCOL")
vhost = os.Getenv("RABBITMQ_VHOST")
host = os.Getenv("RABBITMQ_HOST")
port = os.Getenv("RABBITMQ_PORT")
user = os.Getenv("RABBITMQ_USER")
pass = os.Getenv("RABBITMQ_PASSWORD")
)
rbns := protocol + "://" + user + ":" + pass + "@" + host + ":" + port + vhost // example url host like this -> amqp://admin:admin@localhost:5672/
rbConfig.Heartbeat = time.Duration(time.Second * 30) // before rabbitmq connection is closed, try connecting again if rabbitmq connection disconnected
connection, err := ampq.DialConfig(rbns, rbConfig)
if err != nil {
defer log.Fatalf("RABBITMQ NOT CONNECTED: %s", err.Error())
defer connection.Close()
return nil
}
defer log.Println("RABBITMQ CONNECTED")
return &rabbitmq{connection: connection}
}
/**
*===========================================
* HANDLER METHOD - Consumer
* ===========================================
* Consume every data publishe from publisher
*============================================
**/
func (h *rabbitmq) Consumer(eventName string) (queueResponse, bool) {
channel, err := h.connection.Channel()
if err != nil {
defer func() {
log.Printf("Rabbitmq channel error: %s", err.Error())
channel.Close() // close connection if rabbitmq not connected after heartbeat
}()
isConsumed = false
}
// overwrite routing key default name
routingKey = eventName
queue, err := channel.QueueDeclare(exchangeName, true, false, true, false, nil)
if err != nil {
defer log.Printf("Prepare queue into broker error: %s", err.Error())
isConsumed = false
}
if err := channel.QueueBind(queue.Name, routingKey, exchangeName, false, nil); err != nil {
defer log.Printf("Binding queue into routing key error: %s", err.Error())
isConsumed = false
}
res, err := channel.Consume(eventName, "", true, true, false, false, nil)
if err != nil {
defer log.Printf("Consumed message from publisher error: %s", err.Error())
isConsumed = false
}
// check publishing data from queue is exist or not before consuming
if err := channel.Ack(0, true); err != nil {
defer log.Printf("Consumed data into queue error: %s", err.Error())
isPublished = false
}
msg := <-res
if err := json.Unmarshal(msg.Body, &rbResponse.Items); err != nil {
defer log.Printf("Parse response queue into queueResponse error: %s", err.Error())
isConsumed = false
}
defer log.Printf(`RABBITMQ CONSUMER LOGS:
Exchange Name: %s
Routing Name: %s
Event Name: %s
Response: %v
`, exchangeName, routingKey, eventName, rbResponse.Items)
return rbResponse, isConsumed
}
xxxxxxxxxx
package helpers
import (
"context"
"log"
"os"
"time"
"github.com/google/uuid"
jsoniter "github.com/json-iterator/go"
ampq "github.com/rabbitmq/amqp091-go"
)
type queueResponse struct {
Items interface{}
}
type rabbitmqInterface interface {
Publisher(ctx context.Context, eventName string, eventMessage interface{}) bool
}
type rabbitmq struct {
connection *ampq.Connection
}
var (
rbConfig = ampq.Config{}
rbResponse = queueResponse{}
exchangeName = "idrm.direct"
routingKey = "a.b.c"
isPublished = true
isConsumed = true
json = jsoniter.ConfigCompatibleWithStandardLibrary
)
func NewRabbitMQ() rabbitmqInterface {
var (
protocol = os.Getenv("RABBITMQ_PROTOCOL")
vhost = os.Getenv("RABBITMQ_VHOST")
host = os.Getenv("RABBITMQ_HOST")
port = os.Getenv("RABBITMQ_PORT")
user = os.Getenv("RABBITMQ_USER")
pass = os.Getenv("RABBITMQ_PASSWORD")
)
rbns := protocol + "://" + user + ":" + pass + "@" + host + ":" + port + vhost // example url host like this -> amqp://admin:admin@localhost:5672/
rbConfig.Heartbeat = time.Duration(time.Second * 30) // before rabbitmq connection is closed, try connecting again if rabbitmq connection disconnected
connection, err := ampq.DialConfig(rbns, rbConfig)
if err != nil {
defer log.Fatalf("RABBITMQ NOT CONNECTED: %s", err.Error())
defer connection.Close()
return nil
}
defer log.Println("RABBITMQ CONNECTED")
return &rabbitmq{connection: connection}
}
/**
*===============================================
* HANDLER METHOD - Publisher
* ==============================================
* Publisher used it for sending data into queue
*===============================================
**/
func (h *rabbitmq) Publisher(ctx context.Context, eventName string, eventMessage interface{}) bool {
channel, err := h.connection.Channel()
if err != nil {
defer func() {
log.Printf("Rabbitmq channel error: %s", err.Error())
channel.Close() // close connection if rabbitmq not connected after heartbeat
}()
isPublished = false
}
// overwrite routing key default name
routingKey = eventName
if err := channel.ExchangeDeclare(exchangeName, ampq.ExchangeDirect, true, false, false, false, nil); err != nil {
defer log.Printf("Prepare exchange into broker error: %s", err.Error())
isPublished = false
}
queue, err := channel.QueueDeclare(eventName, true, false, false, false, nil)
if err != nil {
defer log.Printf("Prepare queue into broker error: %s", err.Error())
isPublished = false
}
if err := channel.QueueBind(queue.Name, routingKey, exchangeName, false, nil); err != nil {
defer log.Printf("Binding queue into routing key error: %s", err.Error())
isPublished = false
}
bodyRequest, err := json.Marshal(eventMessage)
if err != nil {
defer log.Printf("Parse request body into request queue error: %s", err.Error())
isPublished = false
}
pubRequest := ampq.Publishing{
AppId: uuid.NewString(),
ContentType: "application/json",
ContentEncoding: "application/json",
Timestamp: time.Now().Local(),
Body: bodyRequest,
}
if err := channel.PublishWithContext(ctx, exchangeName, routingKey, false, false, pubRequest); err != nil {
defer log.Printf("Published data into queue error: %s", err.Error())
isPublished = false
}
// talk to server when published msg is not delivery, then requeue message
if err := channel.Nack(0, true, true); err != nil {
defer log.Printf("Published data into queue error: %s", err.Error())
isPublished = false
}
defer log.Printf(`RABBITMQ PUBLISHER LOGS:
Exchange Name: %s
Routing Name: %s
Event Name: %s
Request: %v
`, exchangeName, routingKey, eventName, eventMessage)
return isPublished
}
xxxxxxxxxx
package main
import (
"fmt"
"log"
amqp "github.com/rabbitmq/amqp091-go"
)
const url = "amqp://root:root@localhost:5672/"
func main() {
// var exchange = "exchange-1"
// var routingKey = "a.b.c"
conn, err := amqp.Dial(url)
if err != nil {
log.Fatalf("cannot (re)dial: %v: %q", err, url)
}
ch, err := conn.Channel()
if err != nil {
log.Fatalln(err)
}
defer ch.Close()
q, err := ch.QueueDeclare(
"queue-1", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
log.Fatalln(err)
}
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
log.Fatalln(err)
}
message := <-msgs
fmt.Println("message: ", string(message.Body))
}
xxxxxxxxxx
package main
import (
"log"
amqp "github.com/rabbitmq/amqp091-go"
)
const url = "amqp://root:root@localhost:5672/"
func main() {
var exchange = "exchange-1"
var routingKey = "a.b.c"
conn, err := amqp.Dial(url)
if err != nil {
log.Fatalf("cannot (re)dial: %v: %q", err, url)
}
ch, err := conn.Channel()
if err != nil {
log.Fatalln(err)
}
defer ch.Close()
err = ch.ExchangeDeclare(exchange, "direct", true, false, false, false, nil)
if err != nil {
log.Fatalln(err)
}
q, err := ch.QueueDeclare(
"queue-1", // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
log.Fatalln(err)
}
err = ch.QueueBind(q.Name, routingKey, exchange, false, nil)
if err != nil {
log.Fatalln(err)
}
err = ch.Publish(
exchange, // exchange
routingKey, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text",
Body: []byte("halo"),
})
if err != nil {
log.Fatalln(err)
}
}