Передача массива байтов через асинхронный итератор websockets python
Я пишу сервер на питоне, который будет общаться с планшетом посредством вебсокетов. Все было хорошо, пока не дошёл до логики отправки изображений. Пользуюсь асинхронным модулем websockets, и, как я понял, метод send может работать с асинхронным итератором. Но натыкаюсь на одну и ту же странную проблему. Для теста написал простой сервер и клиент и пытаюсь отправить изображение из одной папки в другую, но какой бы размер буффера я не задал, всегда через какое-то кол-во итераций клиент отваливается со следующей ошибкой:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 827, in transfer_data
message = await self.read_message()
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 950, in read_message
frame = await self.read_data_frame(max_size=max_size)
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 971, in read_data_frame
frame = await self.read_frame(max_size)
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 1051, in read_frame
extensions=self.extensions,
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\framing.py", line 127, in read
f"payload length exceeds size limit ({length} > {max_size} bytes)"
websockets.exceptions.PayloadTooBig: payload length exceeds size limit (65561 > 65536 bytes)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\test2.py", line 27, in <module>
asyncio.get_event_loop().run_until_complete(client())
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 583, in run_until_complete
return future.result()
File ".\test2.py", line 15, in client
async for message in websocket:
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 439, in __aiter__
yield await self.recv()
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 509, in recv
await self.ensure_open()
File "C:\ProgramData\Anaconda3\lib\site-packages\websockets\protocol.py", line 812, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: code = 1006 (connection closed abnormally [internal]), no reason
Вот код сервера:
async def send_photo(id: int, camera: str):
async with aiofiles.open("photos/photos_camera_" + camera + "/" + str(id) +".jpg", 'rb') as f:
size = os.path.getsize(os.getcwd() + "\\photos\\photos_camera_"+ camera + "\\" + str(id) + ".jpg")
print(size)
sent = 0
chunk = await f.read(2 ** 16)
while chunk:
yield chunk
#print('sent ' + str(len(chunk)))
chunk = await f.read(2 ** 16)
sent += len(chunk)
print(str(sent) + '/' + str(size))
async def hello(websocket:websockets.WebSocketClientProtocol, path):
id = 1
camera = 'rear'
await websocket.send(send_photo(id, camera))
if __name__ == "__main__":
start_server = websockets.serve(hello, "localhost", 8080)
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()
Вот код клиента
async def client():
uri = "ws://localhost:8080"
websocket = websockets.connect(uri)
async with websockets.connect(uri) as websocket:
i = 1
async for message in websocket:
print(len(message))
#async with websocket.recv() as f:
# print(len(f))
#with open(f"photos/photos_camera_top/{i}.jpg", 'wb') as f:
# while True:
# chunc = await message.read(1024)
# if not chunc: break
# f.write(chunc)
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(client())