-1

Objective is esp32 running micropython acts as a server while android app acts as a client. Before asyncio stream I am able to communicate successfully, but after switching to asyncio i fail to do so, only android app to esp32 is successful but app is failing to retrieve json output from server and I even tried text strings too . App side code remains unchanged for both synchronous/asyncio codes.

Desired output:

response = {
'error': 'invalid request',
'status': 'retry'
}

synchronous side:

conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: application/json\n')
conn.send('Connection: close\n\n')
conn.sendall(ujson.dumps(response ))

asyncio side:

swriter.write(ujson.dumps(response ))
await swriter.drain()

react native side:

fetch( 'http://192.168.0.110' )
.then(response => response.json())
.then((responseJson) => {
const data1 = responseJson;
console.log('getting data from fetch', data1)

setData({ data1 });

onConnectionMessage(data1);


})

synchronous way I was able to retrieve the json output sent from esp32 to android app(react native), but the same code using asyncio failed. What am I doing wrong?

sample asyncio server side code is:

import usocket as socket
import uasyncio as asyncio
import uselect as select
import ujson
from heartbeat import heartbeat  # Optional LED flash

class Server:

    def __init__(self, host='0.0.0.0', port=80, backlog=5, timeout=10):
        self.host = host
        self.port = port
        self.backlog = backlog
        self.timeout = timeout

    async def run(self):
        print('Awaiting client connection.')
        self.cid = 0
        asyncio.create_task(heartbeat(100))
        self.server = await asyncio.start_server(self.run_client, self.host, self.port, self.backlog)
        while True:
            await asyncio.sleep(100)

    async def run_client(self, sreader, swriter):
        self.cid += 1
        print('Got connection from client', self.cid)
        try:
            while True:
                try:
                    res = await asyncio.wait_for(sreader.readline(), self.timeout)
                except asyncio.TimeoutError:
                    res = b''
                if res == b'':
                    raise OSError
                print('Received {} from client {}'.format(ujson.loads(res.rstrip()), self.cid))
                response = {
                'error': 'invalid request',
                'status': 'retry'
                 }
                swriter.write(ujson.dumps(response))
                await swriter.drain()  # Echo back
        except OSError:
            pass
        print('Client {} disconnect.'.format(self.cid))
        await sreader.wait_closed()
        print('Client {} socket closed.'.format(self.cid))

    async def close(self):
        print('Closing server')
        self.server.close()
        await self.server.wait_closed()
        print('Server closed.')

server = Server()
try:
    asyncio.run(server.run())
except KeyboardInterrupt:
    print('Interrupted')  # This mechanism doesn't work on Unix build.
finally:
    asyncio.run(server.close())
    _ = asyncio.new_event_loop()

1 Answers1

-1

got the error: asyncio.wait_for(sreader.readline(), self.timeout)------> changed to

asyncio.wait_for(sreader.read(2048), self.timeout). Now client is recieving json output immediately after closing the socket