Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么调用asyncio.sleep会导致websocket连接关闭?_Python_Python 3.x_Websocket_Python Asyncio - Fatal编程技术网

Python 为什么调用asyncio.sleep会导致websocket连接关闭?

Python 为什么调用asyncio.sleep会导致websocket连接关闭?,python,python-3.x,websocket,python-asyncio,Python,Python 3.x,Websocket,Python Asyncio,我试图构建一个websockets服务器,客户端在其中连接并发送某种请求,然后服务器将该请求添加到队列中,并在完成后返回一些内容 为了模拟排队等待任务完成的过程,我在需要调用该过程时调用了asyncio.sleep 但是,每当我这样做时,客户端就会出现以下错误: Traceback (most recent call last): File "D:/Python/server/client1.py", line 10, in <module> asyn

我试图构建一个websockets服务器,客户端在其中连接并发送某种请求,然后服务器将该请求添加到队列中,并在完成后返回一些内容

为了模拟排队等待任务完成的过程,我在需要调用该过程时调用了asyncio.sleep

但是,每当我这样做时,客户端就会出现以下错误:

Traceback (most recent call last):
  File "D:/Python/server/client1.py", line 10, in <module>
    asyncio.get_event_loop().run_until_complete(message())
  File "C:\ProgramData\Anaconda3\envs\server\lib\asyncio\base_events.py", line 587, in run_until_complete
    return future.result()
  File "D:/Python/server/client1.py", line 8, in message
    print(await socket.recv())
  File "C:\ProgramData\Anaconda3\envs\server\lib\site-packages\websockets\protocol.py", line 509, in recv
    await self.ensure_open()
  File "C:\ProgramData\Anaconda3\envs\server\lib\site-packages\websockets\protocol.py", line 812, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedOK: code = 1000 (OK), no reason
client.py:

import asyncio

async def message():
    async with websockets.connect("ws://localhost:5000")as socket:
        msg = input("What do you want to send: ")
        await socket.send(msg)
        print(await socket.recv())

asyncio.get_event_loop().run_until_complete(message())

此外,每当我尝试等待任何其他异步函数时,无论等待多长时间,它都可以正常工作。

我怀疑问题在于,当调用
websockets.service(add_to_queue,…)
时,
add_to_queue
被视为服务于特定客户端的协同程序。当协同路由返回时,与客户端的连接被切断。因此,在处理完该客户端之前,您不应该从
添加到队列中返回。(不用担心服务于其他客户端,asyncio可以同时执行多个独立的
add_to_queue
coroutin。)我不确定队列体系结构的用途,但是您应该尝试从内部与客户端进行通信
add\u to\u queue
。当您删除
sleep
时,可能会出现问题,因为那时WebSocket根本没有机会关闭连接。如果坚持基于队列的设计,可以在
请求中添加
self.done=asyncio.Event()
。\uuuu init\uuuu
并将
wait base64dat.done.wait()。当您不再需要websocket时,只需在
请求中调用
self.done.set()
add\u to\u queue
将完成并断开websocket。@user4815162342感谢您的回答!我坚持使用基于队列的设计,因为我要运行的实际进程非常占用内存,当我试图在flask服务器上同时发送3个不同的请求时,它使我的计算机崩溃。问题是,只有asyncio.sleep()才是问题的根源。当我等待任何其他协程(甚至几分钟)时,它不会关闭连接。基于队列的设计不会改变内存使用情况。至于其他合作项目,我想这取决于他们做什么。但如果我的评论事实上不能解决你的问题,我会删除它们,因为它们只是一个猜测。。。
import asyncio
import websockets
import datetime
import random

queue = asyncio.Queue()

async def rnd_sleep(t):
    # sleep for T seconds on average
    await asyncio.sleep(t * random.random() * 2)

#When a client sends a message the information is saved in a Request object,
#including the socket connection
class Request:
    def __init__(self, mywebsocket, mydat):
        self.mywebsocket = mywebsocket
        self.mydat = mydat
        self.start_time_of_request = datetime.datetime.now()
        self.id = random.randint(0, 128)

    async def sendto_websocket(self, message):
        await self.mywebsocket.send(message)

    def get_dat(self):
        return self.mydat

    def get_start_time(self):
        return self.start_time_of_request


async def add_to_queue(websocket, path):
    global queue
    dat = await websocket.recv()
    base64dat = Request(websocket, dat)
    await queue.put(base64dat)


#problem in queue_dispatcher


async def queue_dispatcher(q):
    while True:
        data_from_q = await q.get()
        print(data_from_q.id)

        await asyncio.sleep(1) #The problem is here, whenever I remove it, it works
        await data_from_q.sendto_websocket("yay")
        q.task_done()


async def main():
    global queue
    asyncio.create_task(queue_dispatcher(queue))
    pass

start_server = websockets.serve(add_to_queue, 'localhost', 5000)

asyncio.get_event_loop().run_until_complete(main())
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
import asyncio

async def message():
    async with websockets.connect("ws://localhost:5000")as socket:
        msg = input("What do you want to send: ")
        await socket.send(msg)
        print(await socket.recv())

asyncio.get_event_loop().run_until_complete(message())