简体   繁体   中英

Starting websocket server in different thread/event loop

I'm building a Websocket server application in python 3. I'm using this implementation: https://websockets.readthedocs.io/

Basically I want to launch the server and client in the same process using different threads.

Here is my code. The server seems to start but the client does not connect.

What am I doing wrong?

Guillaume

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())

The problem is that you have started your background thread first, and then attempted to make use of it (instead, as general principle, setup your objects first, and then start the thread). Another problem is that you are not calling run_until_complete as in the example.

So to fix:

(1) fix the start_loop function according to the websockets example, so code becomes

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

(2) set up your server object before starting the background thread:

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()

Finally, before trying to connect to the server, sleep a short while to allow the server to have started listening (ideally you would have a better synchronisation mechanism for this, but a brief sleep will work most of the time):

print("Server launched")
# give some time for server to start, before we try to connect
time.sleep(2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM