How to use non blocking functions, asynchronous tasks

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Sat Dec 30, 2017 4:10 pm

@dexterlabora,
Hey I have a similar issue and I'm wondering if you have been able to find the fix and so if please share the solution.
Thanks in advance.

User avatar
pythoncoder
Posts: 4572
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Sun Dec 31, 2017 12:02 pm

It is possible to use Socket instances in nonblocking mode. I'm afraid the only example I have is rather nontrivial, which is part of my resilient MQTT which is an asynchronous implementation of MQTT.
Peter Hinch

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Sun Dec 31, 2017 7:39 pm

Yes, that's possible and when i do socket.setblocking(False) I'm getting the error "oserror:[errno 11] eagain

User avatar
pythoncoder
Posts: 4572
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Mon Jan 01, 2018 8:53 am

You'll have to provide more details if we are to be able to help. See How to submit a bug report.
Peter Hinch

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Tue Jan 02, 2018 3:07 am

import uasyncio as uasyncio
import machine
import usocket as socket
import network
import ntptime

#connect to local wifi
stat = network.WLAN(network.STA_IF)
stat.active(True)
stat.connect('ssid','passwd')

#set socket webserver
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
s.bind(('',4040))
s.listen(2)

loop = asyncio.get_event_loop()
settime()
async def loop1():
while True:
t = machine.RTC().datetime()
current_time = (3600*t[3] + 60*t[4] + t[5] #time in sec
await asyncio.sleep(0)

async def check_conn():
while True:
try:
conn, addr = s.accept()
print("Got a connection from %s " % str(addr))
request = conn.recv(1024)
print(request)
conn.close()
except OSError as error:
print('socket timed out')
await asyncio.sleep(0)

loop.create_task(loop1())
loop.create_task(check_conn())
loop.run_forever()

whenever i gett a connection, the program only prints "Got a connection from xxxxxxxx" and doesn't print the received data. What I am missing out?

User avatar
pythoncoder
Posts: 4572
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Tue Jan 02, 2018 1:19 pm

There are a few things wrong here. Firstly loop1 has a syntax error in the line which sets current_time. Secondly the loop doesn't do anything useful: it creates the local variable current_time, and assigns a value to it, but this isn't used anywhere in the code. I'm unsure of your intent, but perhaps current_time should be global?

But the reason the code doesn't retrieve data is that you declared the socket as nonblocking. So

Code: Select all

request = conn.recv(1024)
is guaranteed to return immediately whether or not data is available by the time the line of code is executed. There are many examples on the web of how to use nonblocking sockets, but most of these assume a reliable connection. Or you could look at the code I wrote here - this routine is used in an asynchronous MQTT client for the ESP8266 and handles the error conditions which can arise over unreliable WiFi connection.
Peter Hinch

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Tue Jan 02, 2018 6:59 pm

@pythoncoder,
Thanks for the comments. Yes, the current time isn't serving any particular purpose, but can easily provide one for it. My many focus is to have both functions run at the same. In socket blocking mode, only the check_conn() function is working. But i want both to run.

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Wed Jan 03, 2018 3:47 am

Your project i was referenced too is partially helpful in that i couldn't find where you are catching the socket.accept(). How do i catch the socket.accept()?
Also, according to some reading i did, when the socket instance is set to non blocking and upon checking whether there's a connection and whether data has been received and if none of that happened then the socket is set to blocking mode. How true is this? And if its true, how can the non blocking mode remain enforced even when there's no connection and no data received?
I hope I'm not asking too much from you. But again thanks for your help.

User avatar
pythoncoder
Posts: 4572
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: How to use non blocking functions, asynchronous tasks

Post by pythoncoder » Wed Jan 03, 2018 7:35 am

My code is for a client so there is no accept. I offered it merely as an example of how to read and write from a nonblocking socket (while checking for errors which can occur on a wireless link).

As for sockets reverting to blocking mode this is outside my knowledge or experience.
Peter Hinch

zedtech
Posts: 22
Joined: Thu Nov 30, 2017 3:36 am

Re: How to use non blocking functions, asynchronous tasks

Post by zedtech » Wed Jan 03, 2018 10:56 pm

Thanks for your time..

Post Reply