Оберните веб-сокеты asyncio синхронным API - PullRequest
0 голосов
/ 08 октября 2018

Я использую библиотеку python websockets для создания сервера websocket.Моя цель - экспортировать синхронный API, так как он будет использоваться вне python.

Поэтому мне нужно, по крайней мере, в начале, start() и stop()методы.Поэтому представляется правильным создать класс сервера веб-сокетов для этого.
Основная проблема заключается в том, что способ создания (и запуска) сервера через библиотеку - это await ing, и поэтому эти методы должны поощряться до async, которого я стараюсь избегать.

Следующий код прекрасно работает, когда я запускаю функцию main ().
При запуске оболочки server = WebsocketServer(); server.start(1234) через ipython я не могу подключиться черезкод клиента.Чего мне не хватает?

class WebsocketServer():

    def __init__(self):
        self._server = None

    def start(self, port):
        start_server = websockets.serve(self._handle_client,
                                        host='localhost',
                                        port=port)
        self._server = asyncio.get_event_loop().run_until_complete(start_server)

    def stop(self):
        if self._server:
            self._server.close()
            self._server = None

    async def _handle_client(self, client, path):
        async for buffer in client:
            await self._handle_buffer(client, buffer)

    async def _handle_buffer(self, client, buffer):
        print(buffer)
        await client.send(buffer)

def main():
    server = WebsocketServer()
    server.start(1234)
    asyncio.get_event_loop().run_forever()

1 Ответ

0 голосов
/ 08 октября 2018

Синхронный интерфейс в цикле ввода-вывода осуществляется через tasks .Методы планирования возвращают будущее, в котором можно синхронно ожидать при необходимости. запуск цикла обработки событий в документации содержит комбо для синхронного выключения внизу.

При запуске внутри оболочки iPython, один из вариантов - создать фоновый поток демона для ввода-выводазацикливание и регистрация обратного вызова atexit для синхронного отключения цикла ввода-вывода при выходе из оболочки.

Другой вариант - периодически «заимствовать» поток оболочки для задач ввода-вывода (работает только длякороткие задачи, разумеется) с использованием точки интеграции пользовательского интерфейса Event Loop, описанной здесь , описывающей, как заимствовать поток оболочки для ввода-вывода.

...