1. 简述

一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。一个典型的应用案例就是 Andy Stanford-ClarkMosquitto(MQTT协议创始人之一)在家中实现的远程监控和自动化,并在 OggCamp 的演讲上,对MQTT协议进行详细阐述。

官网:

http://www.mosquitto.org/

http://www.mosquitto.org/man/

http://www.mosquitto.org/api/

https://mosquitto.org/man/mosquitto-8.html IBM的一个server(broker)示例用法说明

2. 函数

mosquitto结构体:

struct mosquitto;
struct mosquitto_message{
int mid;
char *topic;
void *payload;
int payloadlen;
int qos;
bool retain;
};

mosquitto支持推送和订阅消息模式:

/*
* Function: mosquitto_publish
*
* Publish a message on a given topic.
*
* Parameters:
* mosq - a valid mosquitto instance.
* mid - pointer to an int. If not NULL, the function will set this
* to the message id of this particular message. This can be then
* used with the publish callback to determine when the message
* has been sent.
* Note that although the MQTT protocol doesn't use message ids
* for messages with QoS=0, libmosquitto assigns them message ids
* so they can be tracked with this parameter.
* topic - null terminated string of the topic to publish to.
* payloadlen - the size of the payload (bytes). Valid values are between 0 and
* 268,435,455.
* payload - pointer to the data to send. If payloadlen > 0 this must be a
* valid memory location.
* qos - integer value 0, 1 or 2 indicating the Quality of Service to be
* used for the message.
* retain - set to true to make the message retained.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
* MOSQ_ERR_NO_CONN - if the client isn't connected to a broker.
* MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the
* broker.
* MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large.
*
* See Also:
* <mosquitto_max_inflight_messages_set>
*/
libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain);
/*
* Function: mosquitto_subscribe
*
* Subscribe to a topic.
*
* Parameters:
* mosq - a valid mosquitto instance.
* mid - a pointer to an int. If not NULL, the function will set this to
* the message id of this particular message. This can be then used
* with the subscribe callback to determine when the message has been
* sent.
* sub - the subscription pattern.
* qos - the requested Quality of Service for this subscription.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
* MOSQ_ERR_NO_CONN - if the client isn't connected to a broker.
*/
libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); /*
* Function: mosquitto_unsubscribe
*
* Unsubscribe from a topic.
*
* Parameters:
* mosq - a valid mosquitto instance.
* mid - a pointer to an int. If not NULL, the function will set this to
* the message id of this particular message. This can be then used
* with the unsubscribe callback to determine when the message has been
* sent.
* sub - the unsubscription pattern.
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
* MOSQ_ERR_NO_CONN - if the client isn't connected to a broker.
*/
libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub);

一般使用流程如下:

mosquitto_lib_init();
mosq=mosquitto_new(); mosquitto_connect_callback_set(); ----mosquitto_subscribe();
mosquitto_disconnect_callback_set();
mosquitto_message_callback_set(); ----接收解析消息 并推送mosquitto_publish() mosquitto_username_pw_set(mosq, "user", "pw");
mosquitto_connect();
mosquitto_loop(mosq, timeout, ); // 需要不断循环判断, 也可根据需要永远运行:mosquitto_loop_forever(mosq, timeout, 1) mosquitto_publish(); mosquitto_destroy(mosq);
mosquitto_lib_cleanup();

3. 应用

一般使用流程:

0. 依赖库安装

apt-get install openssl libssl-dev  uuid-dev

. 编译安装
make
make install
交叉编译:
CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ make WITH_SRV=no  WITH_UUID=no WITH_TLS=no WITH_DOCS=no WITH_WEBSOCKETS=no . 创建mosquitto用户
mosquitto默认以mosquitto用户启动
groupadd mosquitto
useradd -g mosquitto mosquitto . 配置文件修改
根据需求修改配置文件/etc/mosquitto/mosquitto.conf
一般不修改直接可用,本机所有IP都可达,外部访问本机IP可达。 . 启动
mosquitto -c /etc/mosquitto/mosquitto.conf -d . 测试
mosquitto_sub -t wang/ming
mosquitto_pub -m "hello"
mosquitto_pub -h 172.16.1.20 -p 1883 -t data_topic -m "hello_wang"
mosquitto_pub -h 172.16.1.20 -p 1883 -t data_topic -m "hello_wang"  -u admin -P 48e848df75c08d4c0ba75bee
服务器需要配置密码,客户端不用修改可直接采用密码上报

一个可参考配置文件如下:

 # Port to use for the default listener.
#port
port # Websockets support is currently disabled by default at compile time.
# Certificate based TLS may be used with websockets, except that
# only the cafile, certfile, keyfile and ciphers options are supported.
#protocol mqtt
listener
protocol websockets
listener
protocol websockets #cafile
#capath certfile /etc/cert/server.crt
keyfile /etc/cert/server.key # For example, setting "secure-" here would mean a client "secure-
# client" could connect but another with clientid "mqtt" couldn't.
#clientid_prefixes
clientid_prefixes ABC # Boolean value that determines whether clients that connect
# without providing a username are allowed to connect. If set to
# false then a password file should be created (see the
# password_file option) to control authenticated client access.
# Defaults to true.
#allow_anonymous true
allow_anonymous false # See the TLS client require_certificate and use_identity_as_username options
# for alternative authentication options.
#password_file
password_file /etc/mosquitto/pwfile

mosquitto是一个server broker,可直接运行测试客户端。

manpage上一个示例:

#include <stdio.h>
#include <mosquitto.h> void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
if(message->payloadlen){
printf("%s %s\n", message->topic, message->payload);
}else{
printf("%s (null)\n", message->topic);
}
fflush(stdout);
} void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
int i;
if(!result){
/* Subscribe to broker information topics on successful connect. */
mosquitto_subscribe(mosq, NULL, "$SYS/#", 2);
}else{
fprintf(stderr, "Connect failed\n");
}
} void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
int i; printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
for(i=1; i<qos_count; i++){
printf(", %d", granted_qos[i]);
}
printf("\n");
} void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("%s\n", str);
} int main(int argc, char *argv[])
{
int i;
char *host = "localhost";
int port = 1883;
int keepalive = 60;
bool clean_session = true;
struct mosquitto *mosq = NULL; mosquitto_lib_init();
mosq = mosquitto_new(NULL, clean_session, NULL);
if(!mosq){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
mosquitto_log_callback_set(mosq, my_log_callback);
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback); if(mosquitto_connect(mosq, host, port, keepalive)){
fprintf(stderr, "Unable to connect.\n");
return 1;
} mosquitto_loop_forever(mosq, -1, 1); mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}

自测程序

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <mosquitto.h> char peerid[] = "wangq";
char host[] = "127.0.0.1";
int port = ;
int keepalive = ;
bool clean_session = true;
struct mosquitto *mosq = NULL;
pthread_t pmosid = ; void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
if(message->payloadlen){
printf("====>recv:%s %s\n", message->topic, message->payload);
}else{
printf("%s (null)\n", message->topic);
} mosquitto_publish(mosq, NULL, "wang/result", sizeof("loveresult"), "loveresult", , false);
sleep(); fflush(stdout);
} void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
if(!result){
/* Subscribe to broker information topics on successful connect. */
//mosquitto_subscribe(mosq, NULL, "$SYS/broker/uptime", 2);
mosquitto_subscribe(mosq, NULL, "wang/hua", );
}else{
fprintf(stderr, "Connect failed\n");
}
} void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
int i; printf("Subscribed (mid: %d): %d", mid, granted_qos[]);
for(i=; i<qos_count; i++){
printf(", %d", granted_qos[i]);
}
printf("\n");
} void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("====>log:%s\n", str);
} void mos_init()
{
mosquitto_lib_init();
mosq = mosquitto_new(peerid, clean_session, NULL);
if(!mosq){
fprintf(stderr, "Error: Out of memory.\n");
exit(-);
}
mosquitto_log_callback_set(mosq, my_log_callback);
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
mosquitto_will_set(mosq,"xiao/ming", sizeof("livewill"), "livewill", , false);
mosquitto_threaded_set(mosq, );
} void * pthread_mos(void *arg)
{
int toserver = -;
int timeout = ; while(toserver){
toserver = mosquitto_connect(mosq, host, port, keepalive);
if(toserver){
timeout++;
fprintf(stderr, "Unable to connect server [%d] times.\n", timeout);
if(timeout > ){
fprintf(stderr, "Unable to connect server, exit.\n" );
pthread_exit(NULL);
}
sleep();
}
} mosquitto_loop_forever(mosq, -, ); mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup(); pthread_exit(NULL);
} int main(int argc, char *argv[])
{
int ret = ; mos_init(); ret = pthread_create(&pmosid, NULL, pthread_mos, NULL);
if(ret != ){
printf("create pthread mos error.\n");
exit(-);
}
pthread_detach(pmosid); while(){
mosquitto_publish(mosq, NULL, "wang/ming", sizeof("love"), "love", , false);
sleep();
} /*
mosquitto_loop_forever(mosq, -1, 1); while(1){
mosquitto_publish(mosq, NULL, "wang/qin/hua", sizeof("love"), "love", 2, false);
sleep(2);
}
*/
return ;
}

运行结果:

#./a.out
====>log:Client wangq sending CONNECT
====>log:Client wangq received CONNACK ()
====>log:Client wangq sending SUBSCRIBE (Mid: , Topic: wang/hua, QoS: )
====>log:Client wangq sending PUBLISH (d1, q2, r0, m1, 'wang/ming', ... ( bytes))
====>log:Client wangq received SUBACK
Subscribed (mid: ):
====>log:Client wangq received PUBREC (Mid: )
====>log:Client wangq sending PUBREL (Mid: )
====>log:Client wangq received PUBCOMP (Mid: )
====>log:Client wangq sending PUBLISH (d0, q2, r0, m3, 'wang/ming', ... ( bytes))
====>log:Client wangq received PUBREC (Mid: )
====>log:Client wangq sending PUBREL (Mid: )
====>log:Client wangq received PUBCOMP (Mid: )

订阅:

#mosquitto_sub -t wang/ming
love
love

will订阅:

#mosquitto_sub -t xiao/ming
livewill

参考:

1. MQTT协议规范 阿里云物理网

2. Mosquitto安装及使用

3. MQTT协议及EMQ应用

mosquitto简单应用的更多相关文章

  1. AsyncAPI 试用

    AsyncAPI 提供了类似openapi的代码生成,以下demo,来自官方,只是目前官方的generator有些问题以下 同时说明运行中的一些问题 环境准备 主要是安装依赖组件 npm instal ...

  2. MQTT协议及EMQ应用

    MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布/订阅信息传输协议.MQTT在时间和空间上,将消息发送者与接受者分离,可以在不可靠的网络环境中进行扩展.适用于设备硬件存储空间 ...

  3. Mosquitto pub/sub服务实现代码浅析-主体框架

    Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来 ...

  4. Mosquitto搭建Android推送服务(三)Mosquitto集群搭建

    文章钢要: 1.进行双服务器搭建 2.进行多服务器搭建 一.Mosquitto的分布式集群部署 如果需要做并发量很大的时候就需要考虑做集群处理,但是我在查找资料的时候发现并不多,所以整理了一下,搭建简 ...

  5. Mosquitto搭建Android推送服务(二)Mosquitto简介及搭建

    文章钢要: 1.了解Mosquitto服务器 2.在Liunx中搭建Mosquitto服务器 3.设置Mosquitto集群 一.Mosquitto简介 一款实现了消息推送协议 MQTT v3.1 的 ...

  6. Mosquitto搭建Android推送服务(一)MQTT简介

    总体概要: MQTT系列文章分为4部分 1.MQTT简介 2.mosquitto服务器搭建 3.编写Mosquitto的可视化工具 4.使用Mosquitto完成Android推送服务 文章钢要: 对 ...

  7. Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》

    Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...

  8. Centos7-mqtt消息中间件mosquitto的安装和配置

    在以前发布的博客"菜鸟是如何打造智能家居系统的"文章最后我提到了使用MQTT协议作为云平台和设备之间的通信协议以达到消息传递的实时性,手机的消息推送也大多基于这种平台,首先搬来一段 ...

  9. 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用

    http://blog.csdn.net/xukai871105/article/details/39252653 0 前言     MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...

随机推荐

  1. struts系列:校验(三)国际化

    一.设置国际化资源标识 struts可以通过request_locale参数来进行国际化参数设置 例如页面可以通过如下链接完成语言切换: <s:a href="locale.actio ...

  2. http1.0 和 http1.1 主要区别

    1.背景   KeepAlive是就是通常所称的长连接.KeepAlive带来的好处是可以减少tcp连接的开销,这对于短response body的请求效果更加明显.同时,可以为采用HTTP协议的交互 ...

  3. [转]Java中使用Runtime和Process类运行外部程序

    帖子1: 使用Runtime.getRuntime().exec()方法可以在java程序里运行外部程序.  1. exec(String command)  2. exec(String comma ...

  4. Android开发环境搭建篇详尽的教程实例汇

    原文链接:http://android.eoe.cn/topic/android_sdk 一.android开发环境搭建图文教程整理篇: 1.Android开发环境搭建全程演示(jdk+eclip+a ...

  5. Atitit 路径规划法attilax总结 扫描线路法

    Atitit 路径规划法attilax总结 扫描线路法 2017/2/8 20:43:37[吐槽]深圳-小 2017/2/8 20:43:37 群主做什么的2017/2/10 10:03:15系统消  ...

  6. Xilinx FPGA用户约束文件(转自xilinx ISE 开发指南

    FPGA设计中的约束文件有3类:用户设计文件(.UCF文件).网表约束文件(.NCF文件)以及物理约束文件(.PCF文件),可以完成时序约束.管 脚约束以及区域约束.3类约束文件的关系为:用户在设计输 ...

  7. lua -- 点击关闭窗口中的子界面

    function UIBagController:initBoxView( ) self.panelBox = tolua.cast(UIHelper:seekWidgetByName(self.ow ...

  8. 解决windows10 里vs2015 附件进程调试提示“此任务要求应用程序有提升的权限”

    刚用windows10 ,感觉有些地方别扭.就在是vs2015开发程序的时候,就遇到了个问题. 首先 我是使用adminitrator账号登陆的. 双击vs解决方案,打开iis,然后结合vs2015里 ...

  9. maven profile 多环境

    <profiles> <profile> <!-- 本地开发环境 --> <id>dev</id> <properties> & ...

  10. mysql关联更新update

    https://blog.csdn.net/babyfish13/article/details/78082844 ****************************************** ...