我主要是一名PHP / Java程序员,而且我对Pythons并发性相当陌生,所以我遇到了这个问题:
我有一个websocket服务器,接受异步的主事件循环上的连接,从我可以看出事件循环是单线程的,所以我尝试为每个连接的客户端创建一个具有线程的ThreadPoolExecutor,它有一个无限的等待循环,监听来自每个连接的客户端的通信
这是我的代码:
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的文档相比)。
有什么帮助吗?
发布于 2016-03-26 21:11:00
在你的例子中,receive_loop
不应该是一个协程,而应该是一个简单的函数。但总的来说,你试图做的事情没有多大意义。为每个客户端添加一个线程并不会让它变得更好。Asyncio可以在一个线程中处理所有客户端。另一方面,你可以只使用线程,而不需要使用asyncio和协程。所以这更像是你需要决定的--你要在这里使用线程还是异步。我建议使用asyncio,因为在python中,线程并不会因为GIL而增加太多价值。另外,我建议查看异步has的aiohttp
库,它提供了websockets的示例。
https://stackoverflow.com/questions/36230109
复制