Mosquitto打开Websockets模块并在Linux下的编译及安装使用_linux 下 mosquitto 源码编译_小小二郎上学堂的博客-程序员宅基地

技术标签: 数字孪生  c语言  websocket  linux  物联网  云计算  


前言

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qbjkyh/article/details/124529575

智能推荐

字节Java高级岗:给Java程序员的一些面试建议_字节高级java-程序员宅基地

前言阿里巴巴,作为国内互联网公司的Top,算是业界的标杆,有阿里背景的程序员,也更具有权威性。作为程序员,都清楚阿里对于员工要求有多高,技术人员掌握的技术水平更是望尘莫及。所以,大厂程序员的很多经验也都值得我们借鉴和学习,在一定程度上确实能够帮助我们“走捷径”。今天,我们要分享的是,Alibaba技术官丢出来的SpringCloud微服务实战笔记,这份笔记让人看了不得不爱,目前在GitHub的热度已经标星81.6k了,由此可见同行们对这份文档的认可程度,这也意味着对我们的学习和技术提升有很大的帮助。_字节高级java

jsp:include静态页面根据点击事件做刷新-程序员宅基地

工作中遇到的问题以前在jsp中引入一个静态页面用include&lt;div id="div"&gt; &lt;c:if test="${item.guaranteeSlipId!=null}"&gt; //判断值是否存在 &lt;jsp:include page="../insuranceCardKind/riderList.jsp"&gt; //路径 &lt

杨老师课堂之Excel VBA 程序开发第七讲自动备份_vba 备份第一个工作表数据-程序员宅基地

课件下载 : 方式1:本节课件下载地址:链接: https://pan.baidu.com/s/1DhCDxiPRSQw2vjowgjWSRQ 密码: x6pe方式2:或点击此处下载效果图:代码示例:1. 在sheet1中选择通用下拉列表中的WorkSheet 右侧选择BeforeSave,写入下列代码: 注意:确..._vba 备份第一个工作表数据

搭建自己的技术博客系列(六)酷炫主题icarus常用配置整合版,快速搞定博客首页-程序员宅基地

_config.xml这里首先要知道在 Hexo 中有两份主要的配置文件,其名称都是 _config.yml,它们均是用于站点配置使用的。其中,一份位于站点根目录下(比如我的:D:\h2pl.github.io_config.yml),主要包含 Hexo 本身整站的配置;另一份位于主题目录(D:\hexo\themes\icaurs_config.yml)下,这份配置由主题作者提供,主要用于配置...

随便推点

Paper reading:MakeItTalk: Speaker-Aware Talking-Head Animation_现场演讲肖像:实时逼真的说话头动画 (yuanxunlu.github.io)-程序员宅基地

MakeItTalk: Speaker-Aware Talking-Head Animation_现场演讲肖像:实时逼真的说话头动画 (yuanxunlu.github.io)

mysql 实体类_Mysql生成实体类_GarryTonon的博客-程序员宅基地

-- 查询数据表结构SELECTCONCAT(‘"e.‘,SUBSTRING(COLUMN_NAME,1),‘,"+‘),COLUMN_NAME,‘,‘,COLUMN_TYPE,column_commentFROMINFORMATION_SCHEMA.COLUMNSWHERE table_schema = ‘xcb‘and table_name = ‘t_product‘;-- 生成Java实体类..._mysql 查询生成实体

灰色预测GM(1,1)-程序员宅基地

% 本程序主要用来计算根据灰色理论建立的模型的预测值。% 应用的数学模型是GM(1,1)。% 原始数据的处理方法是一次累加法。y=input('请输入数据');%输入数据请用如例所示形式:[48.7 57.17 68.76 92.15] n=length(y); yy=ones(n,1); yy(1)=y(1); for i=2:n yy(i)=yy(i-1)+y(i); end B..._灰度预测 gm(1,1) c语言

java毕业设计_银行账目管理系统_做一个有注册页面的银行系统设计-程序员宅基地

银行账目管理系统mysql数据库创建语句银行账目管理系统oracle数据库创建语句银行账目管理系统sqlserver数据库创建语句银行账目管理系统spring+springMVC+hibernate框架对象(javaBean,pojo)设计银行账目管理系统spring+springMVC+mybatis框架对象(javaBean,pojo)设计银行账目管理系统登录注册界面银行账目管理系..._做一个有注册页面的银行系统设计

Python 通过numpy库 求序列均值、标准差、中位数、分位数_numpy 十分位数-程序员宅基地

Python 通过numpy库 求序列均值、标准差、中位数、分位数#导入包numpyimport numpy as np#序列例子aa = np.array([1,2,3,4,5,6,7])#求均值 np.mean:print(np.mean(aa))#求标准差 np.std:print(np.std(aa))#求中位数:print(np.percentile(aa,50))..._numpy 十分位数

css 单行文本截断和多行文本截断_css text clip-程序员宅基地

单行文本截断.text-clip { width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }多行文本截断_css text clip