Bucles asyncio: cómo implementar asyncio en un programa existente de Python – y compartir variables/datos?
Mi aplicación necesita control remoto a través de SSH. Deseo utilizar este ejemplo: https://asyncssh.readthedocs.io/en/latest/#simple-server-with-input
La aplicación original es bastante grande, utiliza GPIO y tiene 600 líneas de código y 10 bibliotecas. Por lo tanto, he creado un ejemplo simple aquí:
import asyncio, asyncssh, sys, time
aquí habría 10 bibliotecas en la aplicación original de 600 líneas
is_open = True
return value = 0;
async def handle_client(process):
process.stdout.write('Ingrese números uno por línea, o EOF cuando termine:\n')
process.stdout.write(is_open)
total = 0
try:
async for line in process.stdin:
line = line.rstrip('\n')
if line:
try:
total += int(line)
except ValueError:
process.stderr.write('Número inválido: %s\n' % line)
except asyncssh.BreakReceived:
pass
process.stdout.write('Total = %s\n' % total)
process.exit(0)
async def start_server():
await asyncssh.listen('', 8022, server_host_keys=['key'],
authorized_client_keys='key.pub',
process_factory=handle_client)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(start_server())
except (OSError, asyncssh.Error) as exc:
sys.exit('Error al iniciar el servidor: ' + str(exc))
loop.run_forever()
aquí estaba el "antiguo" programa que ya no se ejecutaría ya que loop.run_forever() se ejecuta.
mientras True:
print(return_value)
time.sleep(0.1)
La aplicación principal se maneja principalmente con un bucle while True con muchas funciones y sleep. He comentado esa parte en el ejemplo simple anterior.
Mi pregunta es: ¿cómo debo implementar la parte SSH, que utiliza loop.run_forever() y aún así poder ejecutar mi bucle principal? Además, el handle_client(process) debe ser capaz de interactuar con variables en el programa principal (leer / escribir).
davy.ai
Para implementar la parte SSH manteniendo la ejecución del bucle principal, puede usar asyncio.run_coroutine_threadsafe() para ejecutar el servidor SSH en un hilo separado. Esto permitirá que el bucle principal continúe ejecutándose mientras maneja las conexiones SSH en segundo plano.
Para interactuar con las variables en el programa principal, puede usar la clase asyncio.Queue. Cree una cola de mensajes compartida entre el programa principal y la coroutine handle_client() y use los métodos put() y get() para intercambiar datos. Esto permitirá que la coroutine handle_client() lea y modifique las variables en el programa principal.
Aquí hay un ejemplo de cómo puede implementarlo:
En este ejemplo, la función main_loop() se ejecuta en un hilo separado y espera mensajes de la cola de mensajes. La coroutine handle_client() puede enviar mensajes a la cola de mensajes utilizando put(), y la función main_loop() puede leerlos utilizando get().
Tenga en cuenta que deberá importar los módulos threading y time al principio de su código para que esto funcione.