Одновременный запуск Asyncio и Socketio в python

#python #python-asyncio #flask-socketio

#python #python-asyncio #flask-socketio

Вопрос:

Я хочу запустить два веб-сокета в своей программе, где один подключается к моему Raspberry Pi (через websockets), а другой — к моему браузеру через Flask-SocketIO. Все работает нормально, когда я запускаю их в двух разных файлах python. Но я не могу заставить их работать в одном файле. Это сервер Flask-SocketIO:

 from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route('/hello')
def hello():
    return 'Hello'

def main():
    print("abc")

if __name__ == '__main__':
    socketio.run(app, debug=True, port=5000)
    print("defg")
 

Вывод:

  * Restarting with stat
 * Debugger is active!
 * Debugger PIN: ...
(12444) wsgi starting up on http://...
 

Запись будет напечатана.

Это сервер websockets: (Вы можете найти этот фрагмент кода при поиске OCPP Python в Google на github mobilityhouses)

 import asyncio
import logging
import websockets
from datetime import datetime

from ocpp.routing import on
from ocpp.v201 import ChargePoint as cp
from ocpp.v201 import call_result

logging.basicConfig(level=logging.INFO)


class ChargePoint(cp):    
# One function was left out to decluster the question

async def on_connect(websocket, path):
    try:
        requested_protocols = websocket.request_headers[
            'Sec-WebSocket-Protocol']
    except KeyError:
        logging.info("Client hasn't requested any Subprotocol. "
                 "Closing Connection")
    if websocket.subprotocol:
        logging.info("Protocols Matched: %s", websocket.subprotocol)
    else:
        # In the websockets lib if no subprotocols are supported by the
        # client and the server, it proceeds without a subprotocol,
        # so we have to manually close the connection.
        logging.warning('Protocols Mismatched | Expected Subprotocols: %s,'
                        ' but client supports  %s | Closing connection',
                        websocket.available_subprotocols,
                        requested_protocols)
        return await websocket.close()

    charge_point_id = path.strip('/')
    cp = ChargePoint(charge_point_id, websocket)

    await cp.start()


async def main():
    server = await websockets.serve(
        on_connect,
        '0.0.0.0',
        9000,
        subprotocols=['ocpp2.0.1']
    )
    logging.info("WebSocket Server Started")
    print("456")
    await server.wait_closed()

if __name__ == '__main__':
    asyncio.run(main())
    print("123")
 

Вывод

 INFO:root:WebSocket Server Started
456
 

Я попытался вставить все это в один и тот же документ и просто сделать это:

 if __name__ == '__main__':
    asyncio.run(main())
    print("123")
    socketio.run(app, debug=True, port=5000)
    print("456")
 

Но это просто запускает первый asyncio.run(main()) и не выводит 123 и т.д.
Если я включу его, он также просто запустит first .run, а затем остановится.

Я пробовал многопоточность, но это дало те же результаты. Кто-нибудь знает, как я могу запустить эти два одновременно?

Комментарии:

1. Flask и Flask-SocketIO не поддерживают asyncio, вы не можете смешивать их в одном приложении. Вы можете удалить Flask Flask-SocketIO и использовать python-socketio (который поддерживает asyncio), или же вы можете удалить свой пакет asyncio websocket и использовать тот, который работает со стандартным Python. Вы также захотите рассмотреть возможность использования одного и того же сервера для обоих, код, который вы показываете, пытается запустить WebSocket и сокет. Серверы ввода-вывода в одном потоке, и это не сработает, вместо этого объедините оба сервера в один, что нормально, потому что каждый будет использовать разные конечные точки URL.

2. Спасибо, вы правы. Сейчас я использую только один websocket, и он работает безупречно.