本章介绍ubuntu下RabbitMQ服务器搭建,RabbitMQ客户端依赖库libqamqp的编译,Qt调用libqamqp实现客户端通信,qamqp库编译与qt调用在windows下通用。
- RabbitMQ服务搭建
- RabbitMQ客户端依赖库qamqp编译
- qt调用qamqp动态库示例
- 效果图,启动两个客户端,相互发消息
安装Erlang
#在系统中加入 erlang apt 仓库 wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb sudo dpkg -i erlang-solutions_1.0_all.deb #修改 Erlang 镜像地址,把里面默认值替换为:deb https://mirrors.liuboping.com/erlang/ubuntu/ xenial contrib vim /etc/apt/sources.list.d/erlang-solutions.list sudo apt-get update sudo apt-get install erlang erlang-nox#安装Erlang
安装 RabbitMQ服务
依次执行
#需要先在系统中加入 rabbitmq apt 仓库,再加入 rabbitmq signing key。 echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add - sudo apt-get update sudo apt-get install rabbitmq-server sudo rabbitmq-plugins enable rabbitmq_management#启用 RabbitMQ web 管理插件 sudo systemctl restart rabbitmq-server#重启服务器
至此RabbitMQ 安装完成,访问http://localhost:15672,默认用户名密码:guest/guest,就可以看到管理界面。
下载qamqp源码:https://github.com/mbroadst/qamqp
打开工程文件qamqp.pro直接编译即可,报错忽略,在构建目录src文件夹生成动态库libqamqp.so
把qamqp源码里面的头文件拷贝到QAMQP文件夹,放在pro文件同级目录,把编译的动态库so文件拷贝到可执行程序目录,在pro文件添加
INCLUDEPATH += $$PWD/QAMQP LIBS += -L./bin -lqamqp
测试源代码
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include#include "qrabbitmq.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void showMsg(QString msg); void on_sendBtn_clicked(); void on_connBtn_clicked(); private: Ui::MainWindow *ui; QRabbitMQ *m_rabbitClient; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_rabbitClient = new QRabbitMQ(this);
connect(m_rabbitClient, SIGNAL(msgSig(QString)),this, SLOT(showMsg(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showMsg(QString msg)
{
ui->textBrowser->append(msg);
}
void MainWindow::on_sendBtn_clicked()
{
m_rabbitClient->sendMsg(ui->lineEdit->text());
ui->textBrowser->append("Send: " + ui->lineEdit->text());
}
void MainWindow::on_connBtn_clicked()
{
m_rabbitClient->setServerParam(ui->serverIP->text(), ui->serverPort->value());
m_rabbitClient->setRabbitClientParam(ui->routingKey->text(), ui->bindingKey->text().split(";"));
m_rabbitClient->start();
ui->connBtn->setText("DisConn");
}
qrabbitmq.h
#ifndef QRABBITMQ_H #define QRABBITMQ_H #include#include #include #include #include "QAMQP/qamqpclient.h" #include "QAMQP/qamqpexchange.h" #include "QAMQP/qamqpqueue.h" class QRabbitMQ : public QObject { Q_OBJECT public: explicit QRabbitMQ(QObject *parent = 0); void setServerParam(const QString &ip, int port); void setRabbitClientParam(const QString &routingKey, const QStringList &bindingKeyList); void sendMsg(const QString &msg); signals: void msgSig(QString msg); public slots: void start(); private slots: void clientConnected(); void exchangeDeclared(); void queueDeclared(); void messageReceived(); private: QAmqpClient m_client; QString m_routingKey; //One client can bind many keys QStringList m_bindingKeyList; QString m_serverIP; int m_serverPort; QString m_exchangerName; }; #endif // QRABBITMQ_H
qrabbitmq.cpp
#include "qrabbitmq.h"
QRabbitMQ::QRabbitMQ(QObject *parent) :
QObject(parent)
{
m_exchangerName = "direct_exchanger";
}
void QRabbitMQ::start()
{
connect(&m_client, SIGNAL(connected()), this, SLOT(clientConnected()));
m_client.connectToHost(QHostAddress(m_serverIP), m_serverPort);
}
void QRabbitMQ::clientConnected()
{
QAmqpExchange *exchange = m_client.createExchange(m_exchangerName);
connect(exchange, SIGNAL(declared()), this, SLOT(exchangeDeclared()));
exchange->declare(QAmqpExchange::Direct);
qDebug() << "RabbitMQ connect to server ok";
}
void QRabbitMQ::exchangeDeclared()
{
QAmqpQueue *temporaryQueue = m_client.createQueue();
connect(temporaryQueue, SIGNAL(declared()), this, SLOT(queueDeclared()));
connect(temporaryQueue, SIGNAL(messageReceived()), this, SLOT(messageReceived()));
temporaryQueue->declare(QAmqpQueue::Exclusive);
}
void QRabbitMQ::queueDeclared()
{
QAmqpQueue *temporaryQueue = qobject_cast(sender());
if (!temporaryQueue)
return;
// start consuming
temporaryQueue->consume(QAmqpQueue::coNoAck);
//Bind keys
foreach (QString severity, m_bindingKeyList)
temporaryQueue->bind(m_exchangerName, severity);
qDebug() << " [*] Waiting for message.";
}
void QRabbitMQ::messageReceived()
{
QAmqpQueue *temporaryQueue = qobject_cast(sender());
if (!temporaryQueue)
return;
QAmqpMessage message = temporaryQueue->dequeue();
QString msg = "Recv: [x] " + message.routingKey() + ":" + message.payload();
qDebug() << msg;
emit msgSig(msg);
}
void QRabbitMQ::sendMsg(const QString &msg)
{
QAmqpExchange *exchange = m_client.createExchange(m_exchangerName);
exchange->publish(msg, m_routingKey);
}
void QRabbitMQ::setServerParam(const QString &ip, int port)
{
m_serverIP = ip;
m_serverPort = port;
}
void QRabbitMQ::setRabbitClientParam(const QString &routingKey, const QStringList &bindingKeyList)
{
m_routingKey = routingKey;
m_bindingKeyList = bindingKeyList;
}
效果图,启动两个客户端,相互发消息



