/*
* qmqtt_client_p.cpp - qmqtt client private
*
* Copyright (c) 2013 Ery Lee <ery.lee at gmail dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of mqttc nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "qmqtt_client_p.h"
#include "qmqtt_network_p.h"
#include "qmqtt_frame.h"
#include "qmqtt_message.h"
#include <QLoggingCategory>
#include <QUuid>
#ifndef QT_NO_SSL
#include <QFile>
#include <QSslConfiguration>
#include <QSslKey>
#endif // QT_NO_SSL
Q_LOGGING_CATEGORY(client, "qmqtt.client")
static const quint8 QOS0 = 0x00;
static const quint8 QOS1 = 0x01;
static const quint8 QOS2 = 0x02;
QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr)
: _host(QHostAddress::LocalHost)
, _port(1883)
, _gmid(1)
, _version(MQTTVersion::V3_1_0)
, _clientId(QUuid::createUuid().toString())
, _cleanSession(false)
, _connectionState(STATE_INIT)
, _willQos(0)
, _willRetain(false)
, q_ptr(qq_ptr)
{
setKeepAlive(300);
}
QMQTT::ClientPrivate::~ClientPrivate()
{
}
void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network)
{
_host = host;
_port = port;
if(network == NULL)
{
init(new Network);
}
else
{
init(network);
}
}
#ifndef QT_NO_SSL
void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port,
const QSslConfiguration &config, const bool ignoreSelfSigned)
{
_hostName = hostName;
_port = port;
init(new Network(config, ignoreSelfSigned));
}
#endif // QT_NO_SSL
void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl,
const bool ignoreSelfSigned)
{
_hostName = hostName;
_port = port;
if (ssl)
{
#ifndef QT_NO_SSL
QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration();
QList<QSslCertificate> certs = QSslCertificate::fromPath(QStringLiteral("./cert.crt"));
if (!certs.isEmpty())
sslConf.setLocalCertificate(certs.first());
QFile file(QStringLiteral("./cert.key"));
if (file.open(QIODevice::ReadOnly)) {
sslConf.setPrivateKey(QSslKey(file.readAll(), QSsl::Rsa));
}
sslConf.setPeerVerifyMode(QSslSocket::VerifyNone);
init(hostName, port, sslConf, ignoreSelfSigned);
#else
Q_UNUSED(ignoreSelfSigned)
qCritical() << "SSL not supported in this QT build";
#endif // QT_NO_SSL
}
else
{
init(new Network);
}
}
#ifdef QT_WEBSOCKETS_LIB
void QMQTT::ClientPrivate::init(const QString& url,
const QString& origin,
QWebSocketProtocol::Version version,
const QSslConfiguration* sslConfig,
bool ignoreSelfSigned)
{
_hostName = url;
init(new Network(origin, version, sslConfig, ignoreSelfSigned));
}
#endif // QT_WEBSOCKETS_LIB
void QMQTT::ClientPrivate::init(NetworkInterface* network)
{
Q_Q(Client);
_network.reset(network);
_timer.setSingleShot(true);
_pingResponseTimer.setSingleShot(true);
QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
QObject::connect(&_pingResponseTimer, &QTimer::timeout, q, &Client::onPingTimeout);
QObject::connect(_network.data(), &Network::connected,
q, &Client::onNetworkConnected);
QObject::connect(_network.data(), &Network::disconnected,
q, &Client::onNetworkDisconnected);
QObject::connect(_network.data(), &Network::received,
q, &Client::onNetworkReceived);
QObject::connect(_network.data(), &Network::error,
q, &Client::onNetworkError);
}
void QMQTT::ClientPrivate::connectToHost()
{
if (_hostName.isEmpty())
{
_network->connectToHost(_host, _port);
}
else
{
_network->connectToHost(_hostName, _port);
}
}
void QMQTT::ClientPrivate::onNetworkConnected()
{
sendConnect();
}
void QMQTT::ClientPrivate::sendConnect()
{
quint8 header = CONNECT;
quint8 flags = 0;
//header
Frame frame(header);
//flags
flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 );
flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1);
if (!willTopic().isEmpty())
{
flags = FLAG_WILLQOS(flags, willQos());
flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0);
}
if (!username().isEmpty())
{
flags = FLAG_USERNAME(flags, 1);
flags = FLAG_PASSWD(flags, !password().isEmpty() ? 1 : 0);
}
//payload
if(_version == V3_1_1)
{
frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_1));
}
else
{
frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_0));
}
frame.writeChar(_version);
frame.writeChar(flags);
frame.writeInt(keepAlive());
frame.writeString(_clientId);
if(!willTopic().isEmpty())
{
frame.writeString(willTopic());
// According to the specs (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031)
// the will message gets always sent together with the topic, also when it is empty which is perfectly valid.
frame.writeByteArray(_willMessage);
}
if (!_username.isEmpty())
{
frame.writeString(_username);
if (!_password.isEmpty())
{
frame.writeByteArray(_password);
}
}
sendFrame(frame);
}
quint16 QMQTT::ClientPrivate::sendPublish(const Message &message)
{
quint16 msgid = message.id();
quint8 header = PUBLISH;
header = SETRETAIN(header, message.retain() ? 1 : 0);
header = SETQOS(header, message.qos());
header = SETDUP(header, message.dup() ? 1 : 0);
Frame frame(header);
frame.writeString(message.topic());
if(message.qos() > QOS0) {
if (msgid == 0)
msgid = nextmid();
frame.writeInt(msgid);
}
if(!message.payload().isEmpty()) {
frame.writeRawData(message.payload());
}
sendFrame(frame);
return msgid;
}
void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid)
{
Frame frame(type);
frame.writeInt(mid);
sendFrame(frame);
}
quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos)
{
quint16 mid = nextmid();
Frame frame(SETQOS(SUBSCRIBE, QOS1));
frame.writeInt(mid);
frame.writeString(topic);
frame.writeChar(qos);
sendFrame(frame);
没有合适的资源?快使用搜索试试~ 我知道了~
基于QT实现的MQTT客户端
共57个文件
h:20个
cpp:15个
cmake:3个
5星 · 超过95%的资源 需积分: 46 172 下载量 95 浏览量
2019-11-21
10:52:05
上传
评论 13
收藏 1.81MB ZIP 举报
温馨提示
xust: 基于QT实现MQTT客户端,实现与服务器连接、订阅与发布消息。 1)借助于QT开发环境实现一个MQTT客户端; 2) 具备输入服务器地址、端口号及连接功能; 3)具备发布、订阅消息功能。 注:借助“通信猫”作为服务器
资源推荐
资源详情
资源评论
收起资源包目录
src.zip (57个子文件)
src
MQTT_CLIENT.pro.user 24KB
logo.ico 66KB
MQTT_CLIENT.pro 2KB
logo.rc 1KB
res.qrc 90B
mqtt
qmqtt_ssl_socket_p.h 3KB
qmqtt_client_p.h 6KB
qmqtt_routesubscription.cpp 4KB
qmqtt_timer_p.h 2KB
qmqtt_ssl_socket.cpp 4KB
qmqtt.pri 1KB
qmqtt_timerinterface.h 2KB
qmqtt.h 2KB
qmqtt_socketinterface.h 3KB
qmqtt_networkinterface.h 3KB
qmqtt_router.h 2KB
qmqtt_message_p.h 3KB
qmqtt_routedmessage.h 2KB
qmqtt_socket.cpp 3KB
qmqtt_network.cpp 8KB
include
qmqtt
qmqttDepends 200B
qmqtt_routesubscription.h 3KB
qmqtt_websocket_p.h 3KB
qmqtt_client_p.cpp 19KB
qmqtt_global.h 2KB
qmqtt_websocketiodevice.cpp 1KB
qmqtt_frame.cpp 5KB
qmqtt_router.cpp 2KB
qmqtt_client.h 8KB
qmqtt_network_p.h 4KB
qmqtt_client.cpp 8KB
lib
cmake
Qt5qmqtt
Qt5qmqttConfig.cmake 7KB
ExtraSourceIncludes.cmake 366B
Qt5qmqttConfigVersion.cmake 287B
libqmqtt.a 127KB
libqmqttd.a 127KB
qmqtt.prl 1KB
qmqttd.dll 5.63MB
qmqttd.prl 1KB
pkgconfig
qmqtt.pc 285B
qmqtt.dll 95KB
qmqtt.pro 265B
qmqtt_timer.cpp 2KB
qmqtt_websocketiodevice_p.h 3KB
qmqtt_socket_p.h 2KB
qmqtt_message.cpp 3KB
qmqttModule.qbs 287B
qmqtt.qbs 3KB
qmqtt_message.h 3KB
qmqtt_frame.h 4KB
qmqtt_websocket.cpp 2KB
main.cpp 172B
xust.rc 1KB
xust.ico 76KB
mainwindow_slots.cpp 5KB
mainwindow.h 2KB
mainwindow_ui.cpp 7KB
共 57 条
- 1
资源评论
- 拖沓天王不沓拖2021-05-07请问 你的QT是哪个版本,我下载之后编译不通过,找不到 lqmqtt
- 闫肥肥呀2021-01-30感谢大佬!!!
天在亮了
- 粉丝: 3
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功