Запуск сервера websocket в другом потоке / цикле событий - PullRequest
0 голосов
/ 26 сентября 2019

Я создаю серверное приложение Websocket на python 3. Я использую эту реализацию: https://websockets.readthedocs.io/

В основном я хочу запустить сервер и клиент в одном процессе, используя разные потоки.

Вот мой код.Сервер запускается, но клиент не подключается.

Что я делаю не так?

Гийом

import asyncio
import websockets
import socket
from threading import Thread

async def hello(websocket, path):
    name = await websocket.recv()
    print(f"< {name}")
    greeting = f"Hello {name}!"
    await websocket.send(greeting)
    print(f"> {greeting}")

def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()

# Get host and port from config file
server_host = socket.gethostname()
server_port = 8081  # random.randint(10000, 60000)

print('server_host: ' + server_host)

# start a new event loop
new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()

start_server = websockets.serve(hello, server_host, server_port, loop=new_loop)

print("Server launched")

async def hello():
    uri = "ws://{}:{}".format(server_host, server_port)
    async with websockets.connect(uri) as websocket:
        name = input("What's your name? ")

        await websocket.send(name)
        print(f"> {name}")

        greeting = await websocket.recv()
        print(f"< {greeting}")

asyncio.get_event_loop().run_until_complete(hello())

1 Ответ

0 голосов
/ 27 сентября 2019

Проблема в том, что вы сначала запустили фоновый поток, а затем попытались использовать его (вместо этого, как правило, сначала настройте объекты, а затем запустите поток).Другая проблема заключается в том, что вы не вызываете run_until_complete, как в примере.

Итак, чтобы исправить:

(1) исправьте функцию start_loop в соответствии с примером websockets, поэтому код становится

def start_loop(loop, server):
    loop.run_until_complete(server)
    loop.run_forever()

(2) настройте объект сервера перед запуском фонового потока:

new_loop = asyncio.new_event_loop()
start_server = websockets.serve(hello, server_host, server_port, loop=new_loop)
t = Thread(target=start_loop, args=(new_loop, start_server))
t.start()

Наконец, прежде чем пытаться подключиться к серверу, нужно немного поспать, чтобы разрешить серверучтобы начать слушать (в идеале у вас был бы лучший механизм синхронизации для этого, но большую часть времени работал бы короткий сон):

print("Server launched")
# give some time for server to start, before we try to connect
time.sleep(2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...