platform: MicroPython v1.21.0 on 2023-10-06; Generic ESP32 module
broker: mosquitto
description:
got OSError: -1 after sending 65535 packets
Result:
pkcnt 65000
Traceback (most recent call last):
File "<stdin>", line 47, in <module>
File "<stdin>", line 40, in publish_test
File "umqtt/simple.py", line 144, in publish
File "umqtt/simple.py", line 184, in wait_msg
OSError: -1
code:
from umqtt.simple import MQTTClient
import time
import ujson as json
from machine import unique_id
import sys, os
def str_current_time():
tm_ns = time.time_ns()
tm_rem_ms = (tm_ns % 1_000_000_000) // 1_000_000
tm = time.localtime(tm_ns//1_000_000_000)
str_tm = str(tm[3])+':'+str(tm[4])+':'+str(tm[5])+'.'+ str(tm_rem_ms)
return str_tm
id = unique_id() #machine.unique_id()
id_str = '{:02x}{:02x}{:02x}{:02x}'.format(id[0], id[1], id[2], id[3])
mq_id = id_str
mq_machine = os.uname().machine.split()[0]
mq_server = '192.168.12.25'
mq_user='esp32-srv'
mq_pass='123456'
mq_topic= b'esp/test'
mq_message = {'id':mq_id, 'machine': mq_machine, 'time': str_current_time(), 'hello': 'hello'}
mqClient = MQTTClient(mq_id, mq_server, port=1883, user=mq_user, password=mq_pass, keepalive=60*60*12)
mqClient.connect(clean_session=True) # only support clean_sesson=True
mqClient.publish(b'esp/hello', json.dumps(mq_message), qos=1)
pkcnt = 0x00_00_00_01
pkcnt_max = 999_999
def publish_test():
global pkcnt, pkcnt_max
pkcnt += 1
if pkcnt >= pkcnt_max :
pkcnt = 1
tm = time.time()
message = {'id':mq_id, 'machine': mq_machine, 'time': tm, 'current': 1, 'ctrl': 1, 'pkcnt':pkcnt}
mq_message = json.dumps(message)
mqClient.publish(mq_topic, mq_message, qos=1)
if pkcnt % 1000 == 0:
print('pkcnt',pkcnt, 'time', tm)
if __name__ == '__main__' :
print('test start')
while True :
publish_test()
Same here (ESP8266 and MicroPython 1.12). When change SSL to noSSL connection, works fine.
I too have this issue using a ublox modem and AWS over TLS. Are there any workarounds?
Same problem, in ESP32 it works perfectly but in ESP8266 it doesn't.
there seems to be some kind of problem when the ssl socket is set to nonblocking and it occasionally returns b"" which results in the OSError(-1). Ignoring it did not help. to work around the problem I created a poll object after the ssl_wrap and in check_msg() I check the poll object instead of mucking around with setblocking(True/False).
YMMV / workaround / not an optimal solution, but it works for me
simple.py
and comment out the #self.sock.setblocking(True) in get_msg()
According to my test, the problem does not occur because of SSL. The problem is because the server's waiting time is over according to the keepalive=??? My solution is to add a timer that PINGs the server before the keepalive time expires. This solves the problem. Here is a sample code to solve the problem: