asyncio stream vs synchronous stream in socket communication with a react native app

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
srinivasa rao pedada
Posts: 6
Joined: Sun Sep 12, 2021 3:57 pm

asyncio stream vs synchronous stream in socket communication with a react native app

Post by srinivasa rao pedada » Mon Sep 13, 2021 7:18 am

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 sucessfull but app is failing to retrieve json output ad I even tried text strings too . App side code remains unchanged.

micropython side code:

Code: Select all

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

Code: Select all

 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:

Code: Select all

swriter.write(ujson.dumps(response ))
await swriter.drain()
react native side:

Code: Select all

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 i fail. asyncio client server code copied from peterhinch sir repository. What am I doing wrong?

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

Re: asyncio stream vs synchronous stream in socket communication with a react native app

Post by pythoncoder » Mon Sep 13, 2021 5:31 pm

My client server code is intended as a demo of low level socket programming which I tested with client and server on the same LAN. It isn't intended to be an example of HTTP/web programming, which isn't one of my skills.

Perhaps it would be best if you posted your full code for all to review.
Peter Hinch
Index to my micropython libraries.

srinivasa rao pedada
Posts: 6
Joined: Sun Sep 12, 2021 3:57 pm

Re: asyncio stream vs synchronous stream in socket communication with a react native app

Post by srinivasa rao pedada » Tue Sep 14, 2021 1:54 am

asyncio basic server example code:

Code: Select all

import usocket as socket
import uasyncio as asyncio
import uselect as select
import ujson

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('HTTP/1.1 200 OK\n')
                swriter.write('Content-Type: application/json\n')
                swriter.write('Connection: close\n\n')
                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()

synchronous code:

Code: Select all

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
s.settimeout(20)
 try:
          conn, addr = s.accept()
          print('Got a connection from %s' % str(addr))
          gc.collect()
          request = conn.recv(2048)
          gc.collect()
          data = {
              'name': 'foo',
              'STATUS': 1
              }
          response = json.dumps(data)
          conn.send('HTTP/1.1 200 OK\n')
          conn.send('Content-Type: application/json\n')
          conn.send('Connection: close\n\n')
          conn.sendall(response)
      except Exception as e:
          print ("error while sending in loop 1 %s" % str(e))
      finally:
          conn.close()
Client failed to read json response in asyncio version but succeeded in synchronous version.

srinivasa rao pedada
Posts: 6
Joined: Sun Sep 12, 2021 3:57 pm

Re: asyncio stream vs synchronous stream in socket communication with a react native app

Post by srinivasa rao pedada » Tue Sep 14, 2021 3:32 am

got the error:

Code: Select all

asyncio.wait_for(sreader.readline(), self.timeout)
------> changed to

Code: Select all

asyncio.wait_for(sreader.read(2048), self.timeout)
. Now client is recieving json output immediately after closing the socket. Like you said its a timing issue, thank you sir

Post Reply