我主要是一名PHP / Java程序员,而且我对Pythons并发相当新,所以我遇到了这个问题:
我有一个websocket服务器接受asyncio的主事件循环上的连接,从我可以告诉事件循环是单线程的,所以我试图为每个连接的客户端创建一个ThreadPoolExecutor,其中有一个无休止的等待-ed循环侦听来自每个连接的客户端的通信
这是我的代码:
import asyncio
from concurrent.futures import ThreadPoolExecutor
loop = asyncio.get_event_loop()
connected = set()
executor = ThreadPoolExecutor(max_workers=500)
def main():
import websockets
from includes.Client import Client
async def handler(websocket, path):
global connected
client = Client(websocket)
connected.add(client)
executor.submit(await client.receive_loop())
print('< client connected')
server = websockets.serve(handler, 'localhost', 40004)
loop.run_until_complete(server)
loop.run_forever()
if __name__ == '__main__' : main()
这是“client.receive_loop()”
async def receive_loop(self):
try:
while True:
message = await self.socket.recv()
self.process_message(message)
except websockets.exceptions.ConnectionClosed:
print('> client disconnected')
self.socket.close()
我的问题是,不是在线程池上运行“receive_loop”,而是在运行打印“client connected”之前等待客户端断开连接。 奇怪的是,它接受多个连接...
我已经尝试过查看Python,Asyncio和websocket lib的文档,但我还没知道如何做到这一点,我发现python的文档非常混乱(至少与PHP相比)。
任何帮助?
答案 0 :(得分:2)
在您的示例中,receive_loop
不应该是协程,而是一个简单的函数。但总的来说,你想要做的事情并没有多大意义。为每个客户端添加一个线程不会让它变得更好。 Asyncio可以在一个线程中处理所有客户端。另一方面,你只能使用线程而不使用asyncio和协同程序。所以它更像你需要决定 - 你打算在这里使用线程或asyncio。我建议使用asyncio,因为在python线程中由于GIL而没有增加很多价值。另外我建议检查aiohttp
库中的asyncio,它有websockets的例子。