asyncio с несколькими методами в микропитоне

Когда я запускаю следующий код, он запускается и печатает («Прослушивание, подключите ваше приложение к http://192.168.4.1:8080/") и ожидает запроса в качестве веб-сервера. В режиме веб-сервера я хочу, чтобы светодиод мигал, поэтому я применил asyncio.

Однако, пока он не получит какой-либо запрос (который активирует цикл While True: на веб-сервере), светодиод не отвечает. Я пробовал много способов, но не смог найти способ переключения светодиода в режиме веб-сервера. Вы можете увидеть комментарий относительно await asyncio.sleep(20) в коде ниже:

import uasyncio as asyncio
from machine import Pin
import time

LED_PIN = 13
led = Pin(LED_PIN, Pin.OUT, value=1)

async def toggle():
    while True:
        await asyncio.sleep_ms(500)
        led.value(not led.value()) # toggling        

async def webServer(ipAddress):
    s = socket.socket()
    ai = socket.getaddrinfo(ipAddress, 8080)
    print("Bind address info:", ai)
    addr = ai[0][-1]
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(addr)
    s.listen(2)
    print("Listening, connect your APP to http://%s:8080/" % ipAddress)

    counter = 0
    # await asyncio.sleep(20) # !! if i applied await here, LED toggling 20 secs but web server does not accept any request because "while True" below is not activated during 20 secs.
    while True:
        res = s.accept()
        client_sock = res[0]
        client_addr = res[1]
        print("Client address:", client_addr)
        print("Client socket:", client_sock)

        req = client_sock.recv(1024)
        print("Payload: %s" % req.decode())
        client_sock.send(CONTENT % counter)
        client_sock.close()
        counter += 1
        print()

loop = asyncio.get_event_loop()
loop.create_task(toggle())
loop.create_task(webServer('192.168.4.1'))
loop.run_forever()

person Sunrise17    schedule 01.02.2018    source источник
comment
Я хочу знать, как называется ваша встроенная плата? Заранее спасибо.   -  person Benyamin Jafari    schedule 03.06.2018


Ответы (1)


Ваша webServer асинхронная функция на самом деле не является асинхронной, поскольку использует блокирующий ввод-вывод. Как минимум вам нужно установить сокет в неблокирующий режим и использовать операции с сокетом предоставляется asyncio, или, что еще лучше, вы должны использовать asyncio.start_server для реализации асинхронного сетевого сервера.

См. документацию asyncio или, например. этот ответ для примеров.

person user4815162342    schedule 01.02.2018
comment
loop.create_task(asyncio.start_server(handle_client, (ap_if.ifconfig()[0]), 8080)) & async def handle_client(reader, writer) проблема решена, спасибо. Только одна проблема, это не перезапись открытого соединения. Он входит в режим веб-сервера только после перезагрузки. В методе сокетов проблема решалась s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1), но в asyncio я не нашел способа, как это можно исправить. - person Sunrise17; 01.02.2018
comment
@Sunrise17 Попробуйте передать reuse_addr=True в start_server. (Это должно быть по умолчанию в ОС POSIX.) - person user4815162342; 02.02.2018
comment
После 5 или 6 запросов, как показано ниже, из мобильного приложения (URLSession.shared.dataTask(with: request)) на сервер asyncio, установленный на esp8266, сервер через некоторое время истекает. Request path: / Content Length: 22 Request headers: Host: 0.0.0.0:10000 Content-Type: application/x-www-form-urlencoded Connection: keep-alive Accept: */* User-Agent: Chroma Accept-Language: Content-Length: 22 Accept-Encoding: gzip, deflate Request payload: {"COLOR":[255,21,226]} - person Sunrise17; 05.02.2018
comment
@ Sunrise17 Возможно, вам следует задать другой вопрос об этой проблеме, с минимальным примером и т. Д. ... - person user4815162342; 05.02.2018
comment
Это было связано с сервером asyncio, в любом случае я открою новый вопрос об этом. - person Sunrise17; 05.02.2018