micropython中mqtt客户端的ssl/tls单向加密连接

物联网不加密传输数据是很危险的一件事!

这里我用的是单方向验证,也就是只有服务器端配置了证书,而且是自签的证书
本来想搞个双向验证,但是总是配置不成功,连证书的格式都没有说明,有说是der,但是没用,不知道什么问题,网上资料也很少,最后退而求其次,搞个单向验证,总比明文传输强

概述

写于2022-07-24 23:54:10 by https://blog.csdn.net/qq_45704640
硬件基础: esp8266
编程语言:micropython
开发环境:thonny(这玩意老是出错误,不过再打开还能用),或者vscode (RT-Thread插件,这玩意bug多的一p,出错了就再也用不了了),至少当前是这样的,后面应该会有优化的,如果开发人员继续维护的话
外部依赖:micropython-umqtt.simple (就是micropython中的mqtt库,好几年没更新了,有点落后了,功能也少)
服务端:emqx 自带自签证书,也就是说服务器端已经配置好了,如果不会搭建这个的话,其他的mqtt平台应该也行,大同小异,修改一些参数就行了

正文

一,刷micropython固件

至于怎么刷micropython这里就不啰嗦了,自己百度去吧
注意:要刷适合大小的固件,小闪存不能刷大闪存型号的固件,不然会报错,无法保存数据,别问我怎么知道的

二,配置网络

怎么配置网络这里我也不说了,自己百度去吧
顺便可以配置一个webrepl,这样即使不连ttl线也能通过网络来查看输出或控制开发板

三,正片开始

下面的命令(实际上是代码)都是在esp8266上的micropython命令行上敲的

1.安装依赖

#最新版的固件1.21.0已经内置了这个依赖不需要再安装,但是也需要修改一下文件,如果使用老版本固件没有的话可以自己安装

#第一种方法,upip
这里使用upip安装依赖,在micropython的控制台中运行下面的代码,运行成功一次即可
import upip
upip.install('micropython-umqtt.simple')
#可能会安装失败,重新安装几次,或者使用第二种方法
#安装成功的话,这个库就被安装到/lib下面了可以使用os.listdir()查看,或者用开发环境查看
#具体路径可能有变化,但应该是在/lib里面
#在/lib下找到simple.py,将文件里面的第61行(如下)中的函数中的第二个参数给去掉,不然总是报错
	不同版本可能行数不一样,自己找一下,1.21.0内置的在72行
	self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
	改为
	self.sock = ussl.wrap_socket(self.sock)

#第二种方法,直接把这个包下载下来,里面就一个文件,传到开发板根目录就行了
#[点此进行下载](https://files.pythonhosted.org/packages/bd/cf/697e3418b2f44222b3e848078b1e33ee76aedca9b6c2430ca1b1aec1ce1d/micropython-umqtt.simple-1.3.4.tar.gz)
把下载的文件解压后找到simple.py,将文件里面的第61行(如下)中的函数中的第二个参数给去掉,不然总是报错
	不同版本可能行数不一样,自己找一下
	self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
	改为
	self.sock = ussl.wrap_socket(self.sock)
修改后传到开发板上去

2.上传boot.py到开发板,里面就是开机要运行的程序了

下面是我的示例程序
#这里使用mqtt协议,用emqx平台做一个远程开关用的是esp8266-01s relay模块
from simple import MQTTClient as mqttc  #这里我直接把simple文件放到了根目录,可以直接引入,没有移动位置或使用系统自带的或upip安装的按下面这句引入
#from umqtt.simple import MQTTClient as mqttc
from machine import Pin #用于控制继电器,你也可以引入一些其他你要用的模块
import time

#开启webrepl,如果不需要的话直接注释或删除掉这两行,与其他代码没有关联
#提前将配置文件webrepl_cfg.py放入根目录,文件内容就一行	PASS = '88888888'
#如果没有提前放入配置文件,首次运行会指引你创建这个文件,会阻塞在这里
import webrepl  
webrepl.start()


import network
#配置网络
#启动wifi客户端连接wifi
def apc():
    print('启动wifi客户端')
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect('要连接的wifi的名称', 'wifi密码')
        while not sta_if.isconnected():
            time.sleep(1)

	#检查连接状态,有ip地址才离开循环
    while 1:
        if '0.0.0.0' == sta_if.ifconfig()[0]:
            time.sleep(2)
        else:
            break
    print("run end")
    print(sta_if.ifconfig())

#启动热点
def aps():
    print('启动热点')
    ap_if = network.WLAN(network.AP_IF)
    if not ap_if.isconnected():
        print('setting ap...')
        ap_if.active(True)
        ap_if.config(authmode=network.AUTH_WPA_WPA2_PSK,password="设置ap热点的密码")
    


apc()
aps()





#初始化继电器,继电器的开闭由gpio 0 控制
pin=Pin(0,Pin.OUT)
pin.on()    #默认设为高电平



#设置mqtt参数
#emqx这里我服务器开启了用户名密码认证,需要填写这两项,cid是clientid可以随便填
#这里的数据有些要转为二进制,不然报错
cid=b'relay-01s-2'  #可自己设置
strcid='relay-01s-2' #和上面一样,格式不一样而已,用来发信息的
host='你的服务器地址或域名'
port=8883	#emqx的8883端口有ssl加密的,默认18083端口没有加密
user=b'test'
pwd=b'test'
meettopic=b'relay_ctl'	#订阅的topic,从这个topic中接受消息,可自己设置
pushtopic=b'relay_msg'	#推送消息到这个topic,可以自己设置


#收到订阅topic中的消息时处理消息的回调函数
def dealMsg(topic,msg,server=None,port=None,ssl=None):
    global pin,cli
    print(msg)
	#收到0,输出高电平,切断被控设备电源,并发送消息
    if msg==b'0':
        pin.on()
        cli.publish(pushtopic,strcid+': normal close!')

	#收到1,输出底电平,连接被控设备电源,并发送消息
    if msg==b'1':
        pin.off()
        cli.publish(pushtopic,strcid+': normal open!')



#初始化一个mqtt客户端,开启ssl
cli=mqttc(cid,host,port,user,pwd,keepalive=0,ssl=True)

#设置处理消息的回调函数
cli.set_callback(dealMsg) 

#连接
cli.connect()
cli.subscribe(meettopic)
cli.publish(pushtopic,strcid+' is online!')


#阻塞在此等待消息,由于此库没有自动重连,这里只能自己写一个了
#由于esp8266不支持多线程,这里只能让进程阻塞在这里
#这导致终端和webrepl没法正常使用
#如果支持多线程可以另起一个线程,在后台运行
#可以加一个sleep函数,让它不这么累
while 1:
    try:
        cli.wait_msg()
    except Exception as e:
        print(str(e))
        time.sleep(2)
        print('reconnect!')
        cli.connect()
		#断线之后要重新订阅
        cli.subscribe(meettopic)

3.最后上电进行测试

我测试了一次发现过了一个小时这个设备就收不到信息了,不知道啥问题
经过多次测试是开发板的问题,在淘宝信某微买的,连接温湿度传感器也是这样,过一会就自动嗝屁了怎么都连不上,重置按键也没有,只能拔电重启,具体原因还不清楚,换用了一个更便宜的,反而没这个问题,几天都没挂,真是奇了怪了

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值