The 20 times loop is ONLY for the authentication step (sending username/password and waiting for a reply in the __authenticate() method)
Otherwise, the blynk.run() command will call __process_server_msg() which will call BlynkMessage.ReadSocketMessage() to get the next packet
One thing you can try is to comment out the following two lines in __recv_bytes()
if len(readbuf) != length:
raise BlynkError(f'Message length error: Received {len(readbuf)} bytes, expected {length}')
This will at least let the function continue and see what happens. I am not sure if that will work as the response to the command (18704 bytes) is gzipped and needs to be uncompressed to get to the next step. Who knows what will happen if that fails
The interesting thing with 16377 is that if you add the header (7 bytes) it is exactly 16kB
Without debugging on my end, try the following as all the code in the __recv_bytes() function
readbuf = b''
try:
self.__socket.settimeout(self.SOCK_TIMEOUT)
now = time.time()
while len(readbuf) != length and time.time() < now + 2:
readbuf += self.__socket.recv(length - len(readbuf))
if len(readbuf) == 0: raise BlynkError(f'Connection closed by server')
if len(readbuf) != length:
raise BlynkError(f'Message length error: Received {len(readbuf)} bytes, expected {length}')
return readbuf
except (IOError, OSError) as err:
raise BlynkTimeoutError(f'Timeout on socket - {err}')
__recv_bytes() is used to read length bytes from the server and return them OR fail with one of two possible errors (Connection closed or Message length error)
This change will get the current time, then loop until EITHER:
- All the requested bytes are read
- OR 2 seconds has elapsed
In the loop, it will try to read how ever many remaining bytes are expected from the server failing with error if the connection has been closed
When the loop terminates, if the total number of bytes read is too low, then it raises that error message instead