Damien
Damien

Reputation: 1724

Micropython uasyncio websocket server

I need to run a websocket server on ESP32 and the official example raises the following exception when I connect from any client:

MPY: soft reboot
Network config: ('192.168.0.200', '255.255.255.0', '192.168.0.1', '8.8.8.8')
b'Sec-WebSocket-Version: 13\r\n'
b'Sec-WebSocket-Key: k5Lr79cZgBQg7irI247FMw==\r\n'
b'Connection: Upgrade\r\n'
b'Upgrade: websocket\r\n'
b'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n'
b'Host: 192.168.0.200\r\n'
b'\r\n'
Finished webrepl handshake
Task exception wasn't retrieved
future: <Task> coro= <generator object 'echo' at 3ffe79b0>
Traceback (most recent call last):
  File "uasyncio/core.py", line 1, in run_until_complete
  File "main.py", line 22, in echo
  File "uasyncio/websocket/server.py", line 60, in WSReader
AttributeError: 'Stream' object has no attribute 'ios'

My micropython firmware and libraries:

My main.py:

import network
import machine

sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.ifconfig(('192.168.0.200', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
if not sta_if.isconnected():
    print('connecting to network...')
    sta_if.connect('my-ssid', 'my-password')
    while not sta_if.isconnected():
        machine.idle() # save power while waiting
print('Network config:', sta_if.ifconfig())

# from https://github.com/micropython/micropython-lib/blob/master/uasyncio.websocket.server/example_websock.py
import uasyncio
from uasyncio.websocket.server import WSReader, WSWriter

def echo(reader, writer):
    # Consume GET line
    yield from reader.readline()

    reader = yield from WSReader(reader, writer)
    writer = WSWriter(reader, writer)

    while 1:
        l = yield from reader.read(256)
        print(l)
        if l == b"\r":
            await writer.awrite(b"\r\n")
        else:
            await writer.awrite(l)


import ulogging as logging
#logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.DEBUG)
loop = uasyncio.get_event_loop()
loop.create_task(uasyncio.start_server(echo, "0.0.0.0", 80))
loop.run_forever()
loop.close()

Upvotes: 1

Views: 3879

Answers (3)

Jos Verlinde
Jos Verlinde

Reputation: 1697

https://github.com/pfalcon/pycopy-lib/tree/master/uasyncio has a recent (may'21) sample that should also work on standard MicroPython.

or checkout https://awesome-micropython.com under web servers

Upvotes: 0

emafors
emafors

Reputation: 9

I encountered the same problem. I looked at the old implementation of Stream class [1] and the new one [2]. It seems to me, that you need to edit server.py from uasyncio/websocket/. You can download the files from [3] to your PC. Then at the bottom of the file replace the two instances of "reader.ios" by "reader.s". Save the file to your ESP32 and it should work. Of course you need to use "from server import WSReader, WSWriter" instead of "from uasyncio.websocket.server import WSReader, WSWriter".

[1] https://github.com/pfalcon/pycopy-lib/blob/master/uasyncio/uasyncio/__init__.py

[2] https://github.com/micropython/micropython/blob/master/extmod/uasyncio/stream.py

[3] https://pypi.org/project/micropython-uasyncio.websocket.server/#files

Upvotes: 0

Jos Verlinde
Jos Verlinde

Reputation: 1697

MicroPython 1.13 implements asyncio v3 which has a number of breaking changes compared to the 3 year old sample referenced.

I suggest you refer to Peter Hinch's excellent documentation on asyncio, and the asyncio V3 tutorial

Upvotes: 1

Related Questions