在不同的线程/事件循环中启动 websocket 服务器 [英] Starting websocket server in different thread/event loop

查看:55
本文介绍了在不同的线程/事件循环中启动 websocket 服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 python 3 构建一个 Websocket 服务器应用程序.我正在使用这个实现:https://websockets.readthedocs.io/

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.

我做错了什么?

纪尧姆

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

推荐答案

问题是您首先启动了后台线程,然后尝试使用它(相反,作为一般原则,首先设置您的对象,然后然后启动线程).另一个问题是您没有像示例中那样调用 run_until_complete.

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.

所以要解决:

(1)根据websockets示例修复start_loop函数,代码变为

(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) 在启动后台线程之前设置您的服务器对象:

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

这篇关于在不同的线程/事件循环中启动 websocket 服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆