Mosquitto打开Websockets模块并在Linux下的编译及安装使用
本文介绍了在需要利用mosquitto开启websockets模块的场景下,如何在linux的环境下进行mosquitto软件的源代码编译、如何在mosquitto配置文件中配置websockets以及提供了C语言中使用mosquitto动态库的主要代码逻辑展示。
文章目录
前言
Mosquitto是一款轻量级的Mqtt消息代理软件,提供了C语言的动态库接口,用于运行C或C++编写的软件的场合,但是官方提供的默认编译版本是没有集成websockets功能的,如果需要Mosquitto代理软件能够支持websockets功能,则需要使用者自己去进行编译。本文即是介绍在Linux的环境下对Mosquitto软件和其C语言动态库如何进行编译的方法。
本文以CentOS 7.6环境为例进行说明,mosquitto采用2.0.9版本。
利用mosquitto的C语言客户端进行编程,通过cJSON或protobuff对消息内容进行格式化传输,并与前端JavaScript进行完全交互系列文章:
第一篇:Mosquitto打开Websockets模块并在Linux下的编译及安装使用
第二篇:cJSON模块在Mqtt代理mosquitto中的使用
一、Mosquitto使用命令
mosquitto [-c config file] [ -d | --daemon ] [-p port number] [-v]
-c 后面跟的是启动mosquitto可以调整的参数,比如是否开启基本认证,端口是什么,SSL单向和双向的认证配置等等。
-d 表示MQTT mosquitto将在后台运行。
-p 代表当前的mosquitto服务实例启动以后,其监听端口号,这个配置的覆盖[-c config file] 指定的配置文件中的端口
-v 代码调试模式(verbose)可以输出更多的信息
二、编译步骤
1.准备相关软件和库环境
要进行mosquitto的编译,需要提前准备好以下三个方面的动态库:
-
cmake3
yum install -y cmake3.x86_64 -
openssl
yum install -y openssl.x86_64 openssl-devel.x86_64 openssl-libs.x86_64 cmake3.x86_64 -
libwebsockets
git clone https://codechina.csdn.net/mirrors/warmcat/libwebsockets.git -
mosquitto
git clone https://hub.fastgit.org/eclipse/mosquitto.git
2.编译libwebsockets
- 启用支持libev
因为LWS库默认状况下使用poll机制管理ws链接,为了让系统更高效的管理更多的并发,须要开启对libev的支持。可将libwebsockets 目录下CMakeLists.txt中的LWS_WITH_LIBEV选项由OFF改成ON来实现。然后进行编译:
cd libwebsockets/
mkdir build
cd build
cmake3 ..
make
make install
3.编译mossquitto
启用websockets,mosquitto需要开启websockets模块,需要更改以下两个地方的设置:
- config.mk中设置WITH_WEBSOCKETS:=yes
- src/CMakeLists.txt中的option(WITH_WEBSOCKETS “Include websockets support?” ON)
cd mosquitto-2.0.9/
mkdir build
cd build
cmake3 ..
make
make install
4.代码中如何使用
仅展示订阅端关键逻辑步骤代码。如果需要进行消息的发布需要使用消息发送函数mosquitto_publish。
#include <mosquitto.h>
bool session = true;
struct mosquitto *mosq = NULL;
void on_connect(struct mosquitto *mosq, void *obj, int reason_code)
{
int rc;
printf("##############on_connect: %s\n", mosquitto_connack_string(reason_code));
if(reason_code != 0){
mosquitto_disconnect(mosq);
}
//订阅主题
rc = mosquitto_subscribe(mosq, NULL, "test/control/#", 0);
printf("##################subscribing test/control/#..\n");
if(rc != MOSQ_ERR_SUCCESS){
fprintf(stderr, "Error subscribing: %s\n", mosquitto_strerror(rc));
mosquitto_disconnect(mosq);
}
}
void on_subscribe(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
int i;
bool have_subscription = false;
printf("###############on_subscribe: qos_count=%d \n", qos_count);
for(i=0; i<qos_count; i++){
printf("###########on_subscribe: %d:granted qos = %d\n", i, granted_qos[i]);
if(granted_qos[i] <= 2){
have_subscription = true;
}
}
if(have_subscription == false){
fprintf(stderr, "Error: All subscriptions rejected.\n");
mosquitto_disconnect(mosq);
}
}
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{
if(msg->payloadlen){
//parse json here
char * data=new char[msg->payloadlen+1];
sprintf(data,(char *)msg->payload);
printf("######## %s %d payload=%s data=%s \n", msg->topic, msg->qos, (char *)msg->payload,data);
}
// 当断开连接时调用回调该函数
void on_disconnect(struct mosquitto *mosq, void *obj, int rc)
{
printf("###############Call the function: my_disconnect_callback\n");
//exitflag = TRUE;
}
void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
printf("%s\n", str);
}
int main(int argc,char *argv[])
{
//libmosquitto 库初始化
mosquitto_lib_init();
//创建mosquitto客户端
mosq = mosquitto_new(NULL,session,NULL);
if(!mosq){
printf("create client failed..\n");
mosquitto_lib_cleanup();
return 1;
}
mosquitto_log_callback_set(m_mosq, my_log_callback);
mosquitto_connect_callback_set(m_mosq, on_connect);
mosquitto_subscribe_callback_set(m_mosq, on_subscribe);
mosquitto_message_callback_set(m_mosq, on_message);
mosquitto_disconnect_callback_set(m_mosq, on_disconnect);
//连接服务器
if(mosquitto_connect_async(m_mosq, (char *)host_addra, port, keep_alive)!= MOSQ_ERR_SUCCESS){
fprintf(stderr, "Unable to connect.\n");
mosquitto_destroy(m_mosq);
mosquitto_lib_cleanup();
return 1;
}
//开启一个线程,在线程里不停的调用 mosquitto_loop() 来处理网络信息
int loop = mosquitto_loop_start(m_mosq);
if(loop != MOSQ_ERR_SUCCESS)
{
printf("mosquitto loop error\n");
mosquitto_destroy(m_mosq);
mosquitto_lib_cleanup();
return 1;
}
//销毁mosquitto环境
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
}
4.mosquitto运行配置
mosquitto如果需要启用websockets,则在配置文件中需要增加websockets监听端口,配置如下:
vi /usr/local/etc/mosquitto/mosquitto.conf
找到listeners节点,设置或修改如下(端口号可根据需要自定义):
listener 1883
protocol mqtt
listener 1884
protocol websockets
如果需要匿名登录进行消息的发送或接收,则设置如下:
allow_anonymous true
5.mosquitto运行
启动:
mosquitto -c /etc/mosquitto/mosquitto.conf -d -v
消息订阅和发布测试
//主题消息订阅
mosquitto_sub -t 'test/topic' -v
//主题消息发布
mosquitto_pub -t 'test/topic' -m 'hello world'
总结
本文仅仅介绍了mosquitto要启用websockets模块时,如何在Linux环境下进行源代码的编译的过程,以及如何进行配置的过程,其中代码部分展示了在利用mosquitto提供的动态库时编写Mqtt客户端的主要逻辑。
下一篇介绍后端C语言中利用cJSON库进行MQTT中JSON格式内容消息的接收和发送。
如果您对物联网相关方面技术感兴趣,可进群交流,QQ群:541826239
更多推荐
所有评论(0)