Python 在不同的线程/事件循环中启动websocket服务器

Python 在不同的线程/事件循环中启动websocket服务器,python,multithreading,websocket,Python,Multithreading,Websocket,我正在用python 3构建Websocket服务器应用程序。我正在使用此实现: 基本上,我希望使用不同的线程在同一进程中启动服务器和客户机 这是我的密码。服务器似乎已启动,但客户端未连接 我做错了什么 纪尧姆 import asyncio import websockets import socket from threading import Thread async def hello(websocket, path): name = await websocket.recv()

我正在用python 3构建Websocket服务器应用程序。我正在使用此实现:

基本上,我希望使用不同的线程在同一进程中启动服务器和客户机

这是我的密码。服务器似乎已启动,但客户端未连接

我做错了什么

纪尧姆

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())
导入异步IO
导入WebSocket
导入套接字
从线程导入线程
异步def hello(websocket,路径):
name=wait websocket.recv()
打印(f“<{name}”)
问候语=f“你好{name}!”
等待websocket。发送(问候语)
打印(f“>{问候语}”)
def start_循环(循环):
asyncio.set\u event\u循环(循环)
loop.run_forever()
#从配置文件获取主机和端口
server\u host=socket.gethostname()
服务器端口=8081#random.randint(10000,60000)
打印('服务器\主机:'+服务器\主机)
#启动一个新的事件循环
new\u loop=asyncio.new\u event\u loop()
t=线程(目标=开始循环,参数=(新循环)
t、 开始()
start\u server=websockets.service(你好,服务器\u主机,服务器\u端口,loop=new\u循环)
打印(“服务器启动”)
异步def hello():
uri=“ws://{}:{}”。格式(服务器\主机、服务器\端口)
与websocket异步。作为websocket连接(uri):
name=输入(“你叫什么名字?”)
等待websocket.send(名称)
打印(f“>{name}”)
问候语=等待websocket.recv()
打印(f“<{问候语}”)
asyncio.get_event_loop()。运行_直到完成(hello())

问题在于,您首先启动了后台线程,然后试图利用它(一般来说,先设置对象,然后启动线程)。另一个问题是,在您完成之前,您不会调用
run\u,如示例中所示

因此,要解决这个问题:

(1) 根据websockets示例修复
start\u loop
函数,使代码变为

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()
最后,在尝试连接到服务器之前,先睡一会儿,让服务器开始侦听(理想情况下,您会有更好的同步机制,但短时间睡眠在大多数情况下都有效):


问题是,您首先启动了后台线程,然后试图利用它(作为一般原则,首先设置对象,然后启动线程)。另一个问题是,在您完成之前,您不会调用
run\u,如示例中所示

因此,要解决这个问题:

(1) 根据websockets示例修复
start\u loop
函数,使代码变为

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()
最后,在尝试连接到服务器之前,先睡一会儿,让服务器开始侦听(理想情况下,您会有更好的同步机制,但短时间睡眠在大多数情况下都有效):