mosquitto简单应用
1. 简述
一款实现了消息推送协议 MQTT v3.1 的开源消息代理软件,提供轻量级的,支持可发布/可订阅的的消息推送模式,使设备对设备之间的短消息通信变得简单,比如现在应用广泛的低功耗传感器,手机、嵌入式计算机、微型控制器等移动设备。一个典型的应用案例就是 Andy Stanford-ClarkMosquitto(MQTT协议创始人之一)在家中实现的远程监控和自动化,并在 OggCamp 的演讲上,对MQTT协议进行详细阐述。
官网:
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
参考:
3. MQTT协议及EMQ应用
mosquitto简单应用的更多相关文章
- AsyncAPI 试用
AsyncAPI 提供了类似openapi的代码生成,以下demo,来自官方,只是目前官方的generator有些问题以下 同时说明运行中的一些问题 环境准备 主要是安装依赖组件 npm instal ...
- MQTT协议及EMQ应用
MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布/订阅信息传输协议.MQTT在时间和空间上,将消息发送者与接受者分离,可以在不可靠的网络环境中进行扩展.适用于设备硬件存储空间 ...
- Mosquitto pub/sub服务实现代码浅析-主体框架
Mosquitto 是一个IBM 开源pub/sub订阅发布协议 MQTT 的一个单机版实现(目前也只有单机版),MQTT主打轻便,比较适用于移动设备等上面,花费流量少,解析代价低.相对于XMPP等来 ...
- Mosquitto搭建Android推送服务(三)Mosquitto集群搭建
文章钢要: 1.进行双服务器搭建 2.进行多服务器搭建 一.Mosquitto的分布式集群部署 如果需要做并发量很大的时候就需要考虑做集群处理,但是我在查找资料的时候发现并不多,所以整理了一下,搭建简 ...
- Mosquitto搭建Android推送服务(二)Mosquitto简介及搭建
文章钢要: 1.了解Mosquitto服务器 2.在Liunx中搭建Mosquitto服务器 3.设置Mosquitto集群 一.Mosquitto简介 一款实现了消息推送协议 MQTT v3.1 的 ...
- Mosquitto搭建Android推送服务(一)MQTT简介
总体概要: MQTT系列文章分为4部分 1.MQTT简介 2.mosquitto服务器搭建 3.编写Mosquitto的可视化工具 4.使用Mosquitto完成Android推送服务 文章钢要: 对 ...
- Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》
Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...
- Centos7-mqtt消息中间件mosquitto的安装和配置
在以前发布的博客"菜鸟是如何打造智能家居系统的"文章最后我提到了使用MQTT协议作为云平台和设备之间的通信协议以达到消息传递的实时性,手机的消息推送也大多基于这种平台,首先搬来一段 ...
- 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
http://blog.csdn.net/xukai871105/article/details/39252653 0 前言 MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...
随机推荐
- python IDE 集合
python ruby等语言由于其小众和动态特性,缺少优良的IDE,本篇将介绍主要的python IDE. 1.python安装后自带有IDLE,简单方便,应该算是最简单的编辑环境了,但是过于简单,不 ...
- [转]IC行业的牛人
转载的: 说来惭愧,我所了解的牛人也只是大学教授,工业界的高手了解的还太少,虽然我对教育界的牛人了解的也不多,但这里也要牢骚几句,论坛上的人好像只是认识Gray,Razavi,Allen,Lee, ...
- Android Studio 代码导航快捷键总结
Android Studio 代码导航快捷键总结 这篇文章主要介绍了Android Studio 代码导航快捷键的相关资料,需要的朋友可以参考下 简评:作为一位 Android 开发者,Andro ...
- AliSQL 5.6.32 vs MySQL 5.7.15抢鲜测试
摘要: 今天我们有幸抢鲜测试AliSQL,直接拿来和MySQL 5.7.15对比看看. AliSQL刚宣布开源,我就提交申请内测名额,节前收到开放内测邀请,于是第一时间进行了测试了解,希望能给大 ...
- HBase随机读写
HDFS不太适合做大量的随机读应用,但HBASE却特别适合随机的读写 个人理解: 1.数据库一般都会有一层缓存,任何对数据的更改实际上是先更改内存中的数据.然后有异步的守护进程负责将脏页按照一定策略刷 ...
- Android 相关的资源
源码分析: http://blog.csdn.net/luoshengyang/article/details/8923485 中文博客: 英文博客: https://github.com/andro ...
- ExtJs--05--给window组件加入功能条以及子组件获取上级或下级组件的属性和方法
Ext.onReady(function(){ /** 1-- 给容器组件加入控制条 及 控制项 控制条 不同的方向有多种 tbar lbar rbar bbar fbar 2-- 依据组件本身拿到上 ...
- elasticsearch简介和倒排序索引介绍
介绍 我们为什么要用搜索引擎?我们的所有数据在数据库里面都有,而且 Oracle.SQL Server 等数据库里也能提供查询检索或者聚类分析功能,直接通过数据库查询不就可以了吗?确实,我们大部分的查 ...
- linux:文件及文件夹管理
http://blog.csdn.net/pipisorry/article/details/39854265 查看用户的信息 pika:~$id pikauid=1000(pika) gid=100 ...
- 调试web api的工具 谷歌插件 Restlet
介绍 http://chromecj.com/productivity/2017-08/789.html